mgltools-gle-1.5.7~rc1~cvs.20130519/0000755000175000017500000000000012146210056015775 5ustar debiandebianmgltools-gle-1.5.7~rc1~cvs.20130519/src/0000755000175000017500000000000012146210061016560 5ustar debiandebianmgltools-gle-1.5.7~rc1~cvs.20130519/src/README.gutil0000644000175000017500000000612410061374075020600 0ustar debiandebian Note to users: turning backfacing culling on may improve performance; will make no visual difference when join style is CAP. ------------------------------------------------------------------- Work left to be done: --------------------- 1) cylnder/cone tesselation should be adaptive ... 2) round-join tessleation should be adaptive. 4) Need to interpolate normal vectors for fillet triangles. Not doing this results in visual artifacts in certain cases. 5) Need to interpolate colors for fillet triangles (not doing this leaves potential for visual artifacts, although I haven't yet seen any.) 6) allow user to install callbacks for V3F, etc (similar to callbacks in gluTess). 7) given i, j point, return actual x,y,z, coords. 10) Some end-caps are concave ... OpenGL GLU utilioty does a sloppy job of concave polygons ... so some of the figures look bad. What to do about this? 11) The ex_raw.c module would probably execute ()some tens of cycles) faster if it had a ex_angle type interface for the normal vector gorp. 13) Testing problem -- I'm worried that contours with only two points will croak the "cut_join" style code. Be sure to test this. 17) polycone raw endcaps are flashing colors -- some kind of bug. 18) Write the @#$%^&*( documentation. ------------------------------------------------------------------- FIXED: ------ 3) round join style not doing backfacing properly at this moment. FIXED 3 June 1993 9) extrusions with more than 64 vertices in the contour may overflow the hardware ... our bgn...end constructs may have to check for such cases ... (for h/w with the 256 vertex limit only). A: Punt. Most hardware today doesn't have this limit anymore. 12) Another significant optimization that can be performed is to convert many of the routines to work along z-axis only. One reason this was not done right off the bat was for readability and maintainability. However, once the code becomes stable, this may be a good idea. (What I mean here is that many routines, such as "intersect()" and "CUTTING_PLANE()" perform operations on x and y coordinates. These are needed for a GENERAL "intersect()" routine; however, the way that they are used below does not require that generality (since all of the drawing occurs parallel to the z-axis). With a little bit of careful thought, the x and y computations could be ripped out). A: But this will not work if there are twists in the contour, since now, extrusions do NOT run parallel to z-axis, and the x,y coordinates are non-trivial. 14) Q: convert extrude.c to work in a bgn/end style of collecting up data? (how to handle 2x3 affine matricies in the bgn/end style?) A: Don't do it. It would make it hard to deal with the per-vertex affine matrices. A much better idea is to implement a C++ object which has a begin-end interface for each poly extrusion object. 15) convert to OpenGL Done. However, see note 10 above. 16) add texture demos that demo the texutre hack. ------------------------------------------------------------------- mgltools-gle-1.5.7~rc1~cvs.20130519/src/segment.c0000644000175000017500000003034510061374075020405 0ustar debiandebian /* * MODULE NAME: segment.c * * FUNCTION: * This module contains code that draws cylinder sections. There are a * number of different segment routines presented: with and without colors, * with and without normals, with and without front and back normals. * * HISTORY: * written by Linas Vepstas August/September 1991 * split into multiple compile units, Linas, October 1991 * added normal vectors Linas, October 1991 * consoldated from other modules, Linas Vepstas, March 1993 * * Copyright (c) 1991,1993,2003 Linas Vepstas */ #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "extrude.h" #include "tube_gc.h" #include "segment.h" #ifndef COLOR_SIGNATURE /* ============================================================ */ void draw_segment_plain (int ncp, /* number of contour points */ gleDouble front_contour[][3], gleDouble back_contour[][3], int inext, double len) { int j; /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j #include "port.h" /* ========================================================== */ /* Zero out a 2D vector */ #define VEC_ZERO_2(a) \ { \ (a)[0] = (a)[1] = 0.0; \ } /* ========================================================== */ /* Zero out a 3D vector */ #define VEC_ZERO(a) \ { \ (a)[0] = (a)[1] = (a)[2] = 0.0; \ } /* ========================================================== */ /* Zero out a 4D vector */ #define VEC_ZERO_4(a) \ { \ (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0; \ } /* ========================================================== */ /* Vector copy */ #define VEC_COPY_2(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ } /* ========================================================== */ /* Copy 3D vector */ #define VEC_COPY(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ (b)[2] = (a)[2]; \ } /* ========================================================== */ /* Copy 4D vector */ #define VEC_COPY_4(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ (b)[2] = (a)[2]; \ (b)[3] = (a)[3]; \ } /* ========================================================== */ /* Vector difference */ #define VEC_DIFF_2(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ } /* ========================================================== */ /* Vector difference */ #define VEC_DIFF(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ (v21)[2] = (v2)[2] - (v1)[2]; \ } /* ========================================================== */ /* Vector difference */ #define VEC_DIFF_4(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ (v21)[2] = (v2)[2] - (v1)[2]; \ (v21)[3] = (v2)[3] - (v1)[3]; \ } /* ========================================================== */ /* Vector sum */ #define VEC_SUM_2(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ } /* ========================================================== */ /* Vector sum */ #define VEC_SUM(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ (v21)[2] = (v2)[2] + (v1)[2]; \ } /* ========================================================== */ /* Vector sum */ #define VEC_SUM_4(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ (v21)[2] = (v2)[2] + (v1)[2]; \ (v21)[3] = (v2)[3] + (v1)[3]; \ } /* ========================================================== */ /* scalar times vector */ #define VEC_SCALE_2(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ } /* ========================================================== */ /* scalar times vector */ #define VEC_SCALE(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ (c)[2] = (a)*(b)[2]; \ } /* ========================================================== */ /* scalar times vector */ #define VEC_SCALE_4(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ (c)[2] = (a)*(b)[2]; \ (c)[3] = (a)*(b)[3]; \ } /* ========================================================== */ /* accumulate scaled vector */ #define VEC_ACCUM_2(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ } /* ========================================================== */ /* accumulate scaled vector */ #define VEC_ACCUM(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ (c)[2] += (a)*(b)[2]; \ } /* ========================================================== */ /* accumulate scaled vector */ #define VEC_ACCUM_4(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ (c)[2] += (a)*(b)[2]; \ (c)[3] += (a)*(b)[3]; \ } /* ========================================================== */ /* Vector dot product */ #define VEC_DOT_PRODUCT_2(c,a,b) \ { \ (c) = (a)[0]*(b)[0] + (a)[1]*(b)[1]; \ } /* ========================================================== */ /* Vector dot product */ #define VEC_DOT_PRODUCT(c,a,b) \ { \ (c) = (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]; \ } /* ========================================================== */ /* Vector dot product */ #define VEC_DOT_PRODUCT_4(c,a,b) \ { \ (c) = (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3] ; \ } /* ========================================================== */ /* vector impact parameter (squared) */ #define VEC_IMPACT_SQ(bsq,direction,position) \ { \ gleDouble len, llel; \ VEC_DOT_PRODUCT (len, (position), (position)); \ VEC_DOT_PRODUCT (llel, (direction), (position)); \ (bsq) = len - llel*llel; \ } /* ========================================================== */ /* vector impact parameter */ #define VEC_IMPACT(bsq,direction,position) \ { \ VEC_IMPACT_SQ((bsq),(direction),(position)); \ (bsq) = sqrt (bsq); \ } /* ========================================================== */ /* Vector length */ #define VEC_LENGTH_2(len,a) \ { \ (len) = (a)[0]*(a)[0] + (a)[1]*(a)[1]; \ (len) = sqrt (len); \ } /* ========================================================== */ /* Vector length */ #define VEC_LENGTH(len,a) \ { \ (len) = (a)[0]*(a)[0] + (a)[1]*(a)[1]; \ (len) += (a)[2]*(a)[2]; \ (len) = sqrt (len); \ } /* ========================================================== */ /* Vector length */ #define VEC_LENGTH_4(len,a) \ { \ (len) = (a)[0]*(a)[0] + (a)[1]*(a)[1]; \ (len) += (a)[2]*(a)[2]; \ (len) += (a)[3] * (a)[3]; \ (len) = sqrt (len); \ } /* ========================================================== */ /* distance between two points */ #define VEC_DISTANCE(len,va,vb) \ { \ gleDouble tmp[4]; \ VEC_DIFF (tmp, (vb), (va)); \ VEC_LENGTH ((len), tmp); \ } /* ========================================================== */ /* Conjugate Length */ #define VEC_CONJUGATE_LENGTH(len,a) \ { \ (len) = 1.0 - (a)[0]*(a)[0] - (a)[1]*(a)[1] - (a)[2]*(a)[2];\ (len) = sqrt (len); \ } /* ========================================================== */ /* Normalize vector length (so that vector is unit length) */ #define VEC_NORMALIZE(a) \ { \ double len; \ VEC_LENGTH (len,a); \ if (len != 0.0) { \ len = 1.0 / len; \ (a)[0] *= len; \ (a)[1] *= len; \ (a)[2] *= len; \ } \ } /* ========================================================== */ /* Change vector length to be newlen */ #define VEC_RENORMALIZE(a,newlen) \ { \ double len; \ VEC_LENGTH (len,a); \ if (len != 0.0) { \ len = (newlen) / len; \ (a)[0] *= len; \ (a)[1] *= len; \ (a)[2] *= len; \ } \ } /* ========================================================== */ /* 3D Vector cross product yeilding vector */ #define VEC_CROSS_PRODUCT(c,a,b) \ { \ (c)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \ (c)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \ (c)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \ } /* ========================================================== */ /* Vector perp -- assumes that n is of unit length * accepts vector v, subtracts out any component parallel to n */ #define VEC_PERP(vp,v,n) \ { \ double dot; \ \ VEC_DOT_PRODUCT (dot, v, n); \ (vp)[0] = (v)[0] - dot * (n)[0]; \ (vp)[1] = (v)[1] - dot * (n)[1]; \ (vp)[2] = (v)[2] - dot * (n)[2]; \ } /* ========================================================== */ /* Vector parallel -- assumes that n is of unit length * Accepts vector v, subtracts out any component perpendicular to n. * That is, it projects vector v to plane defined by n. */ #define VEC_PARALLEL(vp,v,n) \ { \ double dot; \ \ VEC_DOT_PRODUCT (dot, v, n); \ (vp)[0] = dot * (n)[0]; \ (vp)[1] = dot * (n)[1]; \ (vp)[2] = dot * (n)[2]; \ } /* ========================================================== */ /* Vector reflection -- assumes n is of unit length */ /* Takes vector v, reflects it against reflector n, and returns vr. * That is, assumes n defines a plane, and performs a mirror reflection */ #define VEC_REFLECT(vr,v,n) \ { \ double dot; \ \ VEC_DOT_PRODUCT (dot, v, n); \ (vr)[0] = (v)[0] - 2.0 * dot * (n)[0]; \ (vr)[1] = (v)[1] - 2.0 * dot * (n)[1]; \ (vr)[2] = (v)[2] - 2.0 * dot * (n)[2]; \ } /* ========================================================== */ /* Vector blending */ /* Takes two vectors a, b, blends them together */ #define VEC_BLEND(vr,sa,a,sb,b) \ { \ \ (vr)[0] = (sa) * (a)[0] + (sb) * (b)[0]; \ (vr)[1] = (sa) * (a)[1] + (sb) * (b)[1]; \ (vr)[2] = (sa) * (a)[2] + (sb) * (b)[2]; \ } /* ========================================================== */ /* Vector print */ #define VEC_PRINT_2(a) \ { \ double len; \ VEC_LENGTH_2 (len, a); \ printf (#a " is %f %f length of " #a " is %f \n", \ (a)[0], *(a)[1], len); \ } /* ========================================================== */ /* Vector print */ #define VEC_PRINT(a) \ { \ double len; \ VEC_LENGTH (len, (a)); \ printf (#a " is %f %f %f length of " #a " is %f \n", \ (a)[0], (a)[1], (a)[2], len); \ } /* ========================================================== */ /* Vector print */ #define VEC_PRINT_4(a) \ { \ double len; \ VEC_LENGTH_4 (len, (a)); \ printf (#a " is %f %f %f %f length of " #a " is %f \n", \ (a)[0], (a)[1], (a)[2], (a)[3], len); \ } /* ========================================================== */ /* print matrix */ #define MAT_PRINT_4X4(mmm) { \ int i,j; \ printf ("matrix " #mmm " is \n"); \ if ((mmm) == NULL) { \ printf (" Null \n"); \ } else { \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ printf ("%f ", (mmm)[i][j]); \ } \ printf (" \n"); \ } \ } \ } /* ========================================================== */ /* print matrix */ #define MAT_PRINT_3X3(mmm) { \ int i,j; \ printf ("matrix " #mmm " is \n"); \ if ((mmm) == NULL) { \ printf (" Null \n"); \ } else { \ for (i=0; i<3; i++) { \ for (j=0; j<3; j++) { \ printf ("%f ", (mmm)[i][j]); \ } \ printf (" \n"); \ } \ } \ } /* ========================================================== */ /* print matrix */ #define MAT_PRINT_2X3(mmm) { \ int i,j; \ printf ("matrix " #mmm " is \n"); \ if ((mmm) == NULL) { \ printf (" Null \n"); \ } else { \ for (i=0; i<2; i++) { \ for (j=0; j<3; j++) { \ printf ("%f ", (mmm)[i][j]); \ } \ printf (" \n"); \ } \ } \ } /* ========================================================== */ /* initialize matrix */ #define IDENTIFY_MATRIX_3X3(m) \ { \ (m)[0][0] = 1.0; \ (m)[0][1] = 0.0; \ (m)[0][2] = 0.0; \ \ (m)[1][0] = 0.0; \ (m)[1][1] = 1.0; \ (m)[1][2] = 0.0; \ \ (m)[2][0] = 0.0; \ (m)[2][1] = 0.0; \ (m)[2][2] = 1.0; \ } /* ========================================================== */ /* initialize matrix */ #define IDENTIFY_MATRIX_4X4(m) \ { \ (m)[0][0] = 1.0; \ (m)[0][1] = 0.0; \ (m)[0][2] = 0.0; \ (m)[0][3] = 0.0; \ \ (m)[1][0] = 0.0; \ (m)[1][1] = 1.0; \ (m)[1][2] = 0.0; \ (m)[1][3] = 0.0; \ \ (m)[2][0] = 0.0; \ (m)[2][1] = 0.0; \ (m)[2][2] = 1.0; \ (m)[2][3] = 0.0; \ \ (m)[3][0] = 0.0; \ (m)[3][1] = 0.0; \ (m)[3][2] = 0.0; \ (m)[3][3] = 1.0; \ } /* ========================================================== */ /* matrix copy */ #define COPY_MATRIX_2X2(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[0][1]; \ \ (b)[1][0] = (a)[1][0]; \ (b)[1][1] = (a)[1][1]; \ \ } /* ========================================================== */ /* matrix copy */ #define COPY_MATRIX_2X3(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[0][1]; \ (b)[0][2] = (a)[0][2]; \ \ (b)[1][0] = (a)[1][0]; \ (b)[1][1] = (a)[1][1]; \ (b)[1][2] = (a)[1][2]; \ } /* ========================================================== */ /* matrix copy */ #define COPY_MATRIX_3X3(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[0][1]; \ (b)[0][2] = (a)[0][2]; \ \ (b)[1][0] = (a)[1][0]; \ (b)[1][1] = (a)[1][1]; \ (b)[1][2] = (a)[1][2]; \ \ (b)[2][0] = (a)[2][0]; \ (b)[2][1] = (a)[2][1]; \ (b)[2][2] = (a)[2][2]; \ } /* ========================================================== */ /* matrix copy */ #define COPY_MATRIX_4X4(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[0][1]; \ (b)[0][2] = (a)[0][2]; \ (b)[0][3] = (a)[0][3]; \ \ (b)[1][0] = (a)[1][0]; \ (b)[1][1] = (a)[1][1]; \ (b)[1][2] = (a)[1][2]; \ (b)[1][3] = (a)[1][3]; \ \ (b)[2][0] = (a)[2][0]; \ (b)[2][1] = (a)[2][1]; \ (b)[2][2] = (a)[2][2]; \ (b)[2][3] = (a)[2][3]; \ \ (b)[3][0] = (a)[3][0]; \ (b)[3][1] = (a)[3][1]; \ (b)[3][2] = (a)[3][2]; \ (b)[3][3] = (a)[3][3]; \ } /* ========================================================== */ /* matrix transpose */ #define TRANSPOSE_MATRIX_2X2(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[1][0]; \ \ (b)[1][0] = (a)[0][1]; \ (b)[1][1] = (a)[1][1]; \ } /* ========================================================== */ /* matrix transpose */ #define TRANSPOSE_MATRIX_3X3(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[1][0]; \ (b)[0][2] = (a)[2][0]; \ \ (b)[1][0] = (a)[0][1]; \ (b)[1][1] = (a)[1][1]; \ (b)[1][2] = (a)[2][1]; \ \ (b)[2][0] = (a)[0][2]; \ (b)[2][1] = (a)[1][2]; \ (b)[2][2] = (a)[2][2]; \ } /* ========================================================== */ /* matrix transpose */ #define TRANSPOSE_MATRIX_4X4(b,a) \ { \ (b)[0][0] = (a)[0][0]; \ (b)[0][1] = (a)[1][0]; \ (b)[0][2] = (a)[2][0]; \ (b)[0][3] = (a)[3][0]; \ \ (b)[1][0] = (a)[0][1]; \ (b)[1][1] = (a)[1][1]; \ (b)[1][2] = (a)[2][1]; \ (b)[1][3] = (a)[3][1]; \ \ (b)[2][0] = (a)[0][2]; \ (b)[2][1] = (a)[1][2]; \ (b)[2][2] = (a)[2][2]; \ (b)[2][3] = (a)[3][2]; \ \ (b)[3][0] = (a)[0][3]; \ (b)[3][1] = (a)[1][3]; \ (b)[3][2] = (a)[2][3]; \ (b)[3][3] = (a)[3][3]; \ } /* ========================================================== */ /* multiply matrix by scalar */ #define SCALE_MATRIX_2X2(b,s,a) \ { \ (b)[0][0] = (s) * (a)[0][0]; \ (b)[0][1] = (s) * (a)[0][1]; \ \ (b)[1][0] = (s) * (a)[1][0]; \ (b)[1][1] = (s) * (a)[1][1]; \ } /* ========================================================== */ /* multiply matrix by scalar */ #define SCALE_MATRIX_3X3(b,s,a) \ { \ (b)[0][0] = (s) * (a)[0][0]; \ (b)[0][1] = (s) * (a)[0][1]; \ (b)[0][2] = (s) * (a)[0][2]; \ \ (b)[1][0] = (s) * (a)[1][0]; \ (b)[1][1] = (s) * (a)[1][1]; \ (b)[1][2] = (s) * (a)[1][2]; \ \ (b)[2][0] = (s) * (a)[2][0]; \ (b)[2][1] = (s) * (a)[2][1]; \ (b)[2][2] = (s) * (a)[2][2]; \ } /* ========================================================== */ /* multiply matrix by scalar */ #define SCALE_MATRIX_4X4(b,s,a) \ { \ (b)[0][0] = (s) * (a)[0][0]; \ (b)[0][1] = (s) * (a)[0][1]; \ (b)[0][2] = (s) * (a)[0][2]; \ (b)[0][3] = (s) * (a)[0][3]; \ \ (b)[1][0] = (s) * (a)[1][0]; \ (b)[1][1] = (s) * (a)[1][1]; \ (b)[1][2] = (s) * (a)[1][2]; \ (b)[1][3] = (s) * (a)[1][3]; \ \ (b)[2][0] = (s) * (a)[2][0]; \ (b)[2][1] = (s) * (a)[2][1]; \ (b)[2][2] = (s) * (a)[2][2]; \ (b)[2][3] = (s) * (a)[2][3]; \ \ (b)[3][0] = (s) * (a)[3][0]; \ (b)[3][1] = (s) * (a)[3][1]; \ (b)[3][2] = (s) * (a)[3][2]; \ (b)[3][3] = (s) * (a)[3][3]; \ } /* ========================================================== */ /* multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ { \ (b)[0][0] += (s) * (a)[0][0]; \ (b)[0][1] += (s) * (a)[0][1]; \ \ (b)[1][0] += (s) * (a)[1][0]; \ (b)[1][1] += (s) * (a)[1][1]; \ } /* +========================================================== */ /* multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ { \ (b)[0][0] += (s) * (a)[0][0]; \ (b)[0][1] += (s) * (a)[0][1]; \ (b)[0][2] += (s) * (a)[0][2]; \ \ (b)[1][0] += (s) * (a)[1][0]; \ (b)[1][1] += (s) * (a)[1][1]; \ (b)[1][2] += (s) * (a)[1][2]; \ \ (b)[2][0] += (s) * (a)[2][0]; \ (b)[2][1] += (s) * (a)[2][1]; \ (b)[2][2] += (s) * (a)[2][2]; \ } /* +========================================================== */ /* multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ { \ (b)[0][0] += (s) * (a)[0][0]; \ (b)[0][1] += (s) * (a)[0][1]; \ (b)[0][2] += (s) * (a)[0][2]; \ (b)[0][3] += (s) * (a)[0][3]; \ \ (b)[1][0] += (s) * (a)[1][0]; \ (b)[1][1] += (s) * (a)[1][1]; \ (b)[1][2] += (s) * (a)[1][2]; \ (b)[1][3] += (s) * (a)[1][3]; \ \ (b)[2][0] += (s) * (a)[2][0]; \ (b)[2][1] += (s) * (a)[2][1]; \ (b)[2][2] += (s) * (a)[2][2]; \ (b)[2][3] += (s) * (a)[2][3]; \ \ (b)[3][0] += (s) * (a)[3][0]; \ (b)[3][1] += (s) * (a)[3][1]; \ (b)[3][2] += (s) * (a)[3][2]; \ (b)[3][3] += (s) * (a)[3][3]; \ } /* +========================================================== */ /* matrix product */ /* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ #define MATRIX_PRODUCT_2X2(c,a,b) \ { \ (c)[0][0] = (a)[0][0]*(b)[0][0]+(a)[0][1]*(b)[1][0]; \ (c)[0][1] = (a)[0][0]*(b)[0][1]+(a)[0][1]*(b)[1][1]; \ \ (c)[1][0] = (a)[1][0]*(b)[0][0]+(a)[1][1]*(b)[1][0]; \ (c)[1][1] = (a)[1][0]*(b)[0][1]+(a)[1][1]*(b)[1][1]; \ \ } /* ========================================================== */ /* matrix product */ /* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ #define MATRIX_PRODUCT_3X3(c,a,b) \ { \ (c)[0][0] = (a)[0][0]*(b)[0][0]+(a)[0][1]*(b)[1][0]+(a)[0][2]*(b)[2][0];\ (c)[0][1] = (a)[0][0]*(b)[0][1]+(a)[0][1]*(b)[1][1]+(a)[0][2]*(b)[2][1];\ (c)[0][2] = (a)[0][0]*(b)[0][2]+(a)[0][1]*(b)[1][2]+(a)[0][2]*(b)[2][2];\ \ (c)[1][0] = (a)[1][0]*(b)[0][0]+(a)[1][1]*(b)[1][0]+(a)[1][2]*(b)[2][0];\ (c)[1][1] = (a)[1][0]*(b)[0][1]+(a)[1][1]*(b)[1][1]+(a)[1][2]*(b)[2][1];\ (c)[1][2] = (a)[1][0]*(b)[0][2]+(a)[1][1]*(b)[1][2]+(a)[1][2]*(b)[2][2];\ \ (c)[2][0] = (a)[2][0]*(b)[0][0]+(a)[2][1]*(b)[1][0]+(a)[2][2]*(b)[2][0];\ (c)[2][1] = (a)[2][0]*(b)[0][1]+(a)[2][1]*(b)[1][1]+(a)[2][2]*(b)[2][1];\ (c)[2][2] = (a)[2][0]*(b)[0][2]+(a)[2][1]*(b)[1][2]+(a)[2][2]*(b)[2][2];\ } /* ========================================================== */ /* matrix product */ /* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ #define MATRIX_PRODUCT_4X4(c,a,b) \ { \ (c)[0][0] = (a)[0][0]*(b)[0][0]+(a)[0][1]*(b)[1][0]+(a)[0][2]*(b)[2][0]+(a)[0][3]*(b)[3][0];\ (c)[0][1] = (a)[0][0]*(b)[0][1]+(a)[0][1]*(b)[1][1]+(a)[0][2]*(b)[2][1]+(a)[0][3]*(b)[3][1];\ (c)[0][2] = (a)[0][0]*(b)[0][2]+(a)[0][1]*(b)[1][2]+(a)[0][2]*(b)[2][2]+(a)[0][3]*(b)[3][2];\ (c)[0][3] = (a)[0][0]*(b)[0][3]+(a)[0][1]*(b)[1][3]+(a)[0][2]*(b)[2][3]+(a)[0][3]*(b)[3][3];\ \ (c)[1][0] = (a)[1][0]*(b)[0][0]+(a)[1][1]*(b)[1][0]+(a)[1][2]*(b)[2][0]+(a)[1][3]*(b)[3][0];\ (c)[1][1] = (a)[1][0]*(b)[0][1]+(a)[1][1]*(b)[1][1]+(a)[1][2]*(b)[2][1]+(a)[1][3]*(b)[3][1];\ (c)[1][2] = (a)[1][0]*(b)[0][2]+(a)[1][1]*(b)[1][2]+(a)[1][2]*(b)[2][2]+(a)[1][3]*(b)[3][2];\ (c)[1][3] = (a)[1][0]*(b)[0][3]+(a)[1][1]*(b)[1][3]+(a)[1][2]*(b)[2][3]+(a)[1][3]*(b)[3][3];\ \ (c)[2][0] = (a)[2][0]*(b)[0][0]+(a)[2][1]*(b)[1][0]+(a)[2][2]*(b)[2][0]+(a)[2][3]*(b)[3][0];\ (c)[2][1] = (a)[2][0]*(b)[0][1]+(a)[2][1]*(b)[1][1]+(a)[2][2]*(b)[2][1]+(a)[2][3]*(b)[3][1];\ (c)[2][2] = (a)[2][0]*(b)[0][2]+(a)[2][1]*(b)[1][2]+(a)[2][2]*(b)[2][2]+(a)[2][3]*(b)[3][2];\ (c)[2][3] = (a)[2][0]*(b)[0][3]+(a)[2][1]*(b)[1][3]+(a)[2][2]*(b)[2][3]+(a)[2][3]*(b)[3][3];\ \ (c)[3][0] = (a)[3][0]*(b)[0][0]+(a)[3][1]*(b)[1][0]+(a)[3][2]*(b)[2][0]+(a)[3][3]*(b)[3][0];\ (c)[3][1] = (a)[3][0]*(b)[0][1]+(a)[3][1]*(b)[1][1]+(a)[3][2]*(b)[2][1]+(a)[3][3]*(b)[3][1];\ (c)[3][2] = (a)[3][0]*(b)[0][2]+(a)[3][1]*(b)[1][2]+(a)[3][2]*(b)[2][2]+(a)[3][3]*(b)[3][2];\ (c)[3][3] = (a)[3][0]*(b)[0][3]+(a)[3][1]*(b)[1][3]+(a)[3][2]*(b)[2][3]+(a)[3][3]*(b)[3][3];\ } /* ========================================================== */ /* matrix times vector */ #define MAT_DOT_VEC_2X2(p,m,v) \ { \ (p)[0] = (m)[0][0]*(v)[0] + (m)[0][1]*(v)[1]; \ (p)[1] = (m)[1][0]*(v)[0] + (m)[1][1]*(v)[1]; \ } /* ========================================================== */ /* matrix times vector */ #define MAT_DOT_VEC_3X3(p,m,v) \ { \ (p)[0] = (m)[0][0]*(v)[0] + (m)[0][1]*(v)[1] + (m)[0][2]*(v)[2]; \ (p)[1] = (m)[1][0]*(v)[0] + (m)[1][1]*(v)[1] + (m)[1][2]*(v)[2]; \ (p)[2] = (m)[2][0]*(v)[0] + (m)[2][1]*(v)[1] + (m)[2][2]*(v)[2]; \ } /* ========================================================== */ /* matrix times vector */ #define MAT_DOT_VEC_4X4(p,m,v) \ { \ (p)[0] = (m)[0][0]*(v)[0] + (m)[0][1]*(v)[1] + (m)[0][2]*(v)[2] + (m)[0][3]*(v)[3]; \ (p)[1] = (m)[1][0]*(v)[0] + (m)[1][1]*(v)[1] + (m)[1][2]*(v)[2] + (m)[1][3]*(v)[3]; \ (p)[2] = (m)[2][0]*(v)[0] + (m)[2][1]*(v)[1] + (m)[2][2]*(v)[2] + (m)[2][3]*(v)[3]; \ (p)[3] = (m)[3][0]*(v)[0] + (m)[3][1]*(v)[1] + (m)[3][2]*(v)[2] + (m)[3][3]*(v)[3]; \ } /* ========================================================== */ /* vector transpose times matrix */ /* (p)[j] = (v)[0]*(m)[0][j] + (v)[1]*(m)[1][j] + (v)[2]*(m)[2][j]; */ #define VEC_DOT_MAT_3X3(p,v,m) \ { \ (p)[0] = (v)[0]*(m)[0][0] + (v)[1]*(m)[1][0] + (v)[2]*(m)[2][0]; \ (p)[1] = (v)[0]*(m)[0][1] + (v)[1]*(m)[1][1] + (v)[2]*(m)[2][1]; \ (p)[2] = (v)[0]*(m)[0][2] + (v)[1]*(m)[1][2] + (v)[2]*(m)[2][2]; \ } /* ========================================================== */ /* affine matrix times vector */ /* The matrix is assumed to be an affine matrix, with last two * entries representing a translation */ #define MAT_DOT_VEC_2X3(p,m,v) \ { \ (p)[0] = (m)[0][0]*(v)[0] + (m)[0][1]*(v)[1] + (m)[0][2]; \ (p)[1] = (m)[1][0]*(v)[0] + (m)[1][1]*(v)[1] + (m)[1][2]; \ } /* ========================================================== */ /* inverse transpose of matrix times vector * * This macro computes inverse transpose of matrix m, * and multiplies vector v into it, to yeild vector p * * DANGER !!! Do Not use this on normal vectors!!! * It will leave normals the wrong length !!! * See macro below for use on normals. */ #define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \ { \ gleDouble det; \ \ det = (m)[0][0]*(m)[1][1] - (m)[0][1]*(m)[1][0]; \ (p)[0] = (m)[1][1]*(v)[0] - (m)[1][0]*(v)[1]; \ (p)[1] = - (m)[0][1]*(v)[0] + (m)[0][0]*(v)[1]; \ \ /* if matrix not singular, and not orthonormal, then renormalize */ \ if ((det!=1.0) && (det != 0.0)) { \ det = 1.0 / det; \ (p)[0] *= det; \ (p)[1] *= det; \ } \ } /* ========================================================== */ /* transform normal vector by inverse transpose of matrix * and then renormalize the vector * * This macro computes inverse transpose of matrix m, * and multiplies vector v into it, to yeild vector p * Vector p is then normalized. */ #define NORM_XFORM_2X2(p,m,v) \ { \ double len; \ \ /* do nothing if off-diagonals are zero and diagonals are \ * equal */ \ if (((m)[0][1] != 0.0) || ((m)[1][0] != 0.0) || ((m)[0][0] != (m)[1][1])) { \ (p)[0] = (m)[1][1]*(v)[0] - (m)[1][0]*(v)[1]; \ (p)[1] = - (m)[0][1]*(v)[0] + (m)[0][0]*(v)[1]; \ \ len = (p)[0]*(p)[0] + (p)[1]*(p)[1]; \ len = 1.0 / sqrt (len); \ (p)[0] *= len; \ (p)[1] *= len; \ } else { \ VEC_COPY_2 ((p), (v)); \ } \ } /* ========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_2X2(m,v,t) \ { \ (m)[0][0] = (v)[0] * (t)[0]; \ (m)[0][1] = (v)[0] * (t)[1]; \ \ (m)[1][0] = (v)[1] * (t)[0]; \ (m)[1][1] = (v)[1] * (t)[1]; \ } /* ========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_3X3(m,v,t) \ { \ (m)[0][0] = (v)[0] * (t)[0]; \ (m)[0][1] = (v)[0] * (t)[1]; \ (m)[0][2] = (v)[0] * (t)[2]; \ \ (m)[1][0] = (v)[1] * (t)[0]; \ (m)[1][1] = (v)[1] * (t)[1]; \ (m)[1][2] = (v)[1] * (t)[2]; \ \ (m)[2][0] = (v)[2] * (t)[0]; \ (m)[2][1] = (v)[2] * (t)[1]; \ (m)[2][2] = (v)[2] * (t)[2]; \ } /* ========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_4X4(m,v,t) \ { \ (m)[0][0] = (v)[0] * (t)[0]; \ (m)[0][1] = (v)[0] * (t)[1]; \ (m)[0][2] = (v)[0] * (t)[2]; \ (m)[0][3] = (v)[0] * (t)[3]; \ \ (m)[1][0] = (v)[1] * (t)[0]; \ (m)[1][1] = (v)[1] * (t)[1]; \ (m)[1][2] = (v)[1] * (t)[2]; \ (m)[1][3] = (v)[1] * (t)[3]; \ \ (m)[2][0] = (v)[2] * (t)[0]; \ (m)[2][1] = (v)[2] * (t)[1]; \ (m)[2][2] = (v)[2] * (t)[2]; \ (m)[2][3] = (v)[2] * (t)[3]; \ \ (m)[3][0] = (v)[3] * (t)[0]; \ (m)[3][1] = (v)[3] * (t)[1]; \ (m)[3][2] = (v)[3] * (t)[2]; \ (m)[3][3] = (v)[3] * (t)[3]; \ } /* +========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \ { \ (m)[0][0] += (v)[0] * (t)[0]; \ (m)[0][1] += (v)[0] * (t)[1]; \ \ (m)[1][0] += (v)[1] * (t)[0]; \ (m)[1][1] += (v)[1] * (t)[1]; \ } /* +========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \ { \ (m)[0][0] += (v)[0] * (t)[0]; \ (m)[0][1] += (v)[0] * (t)[1]; \ (m)[0][2] += (v)[0] * (t)[2]; \ \ (m)[1][0] += (v)[1] * (t)[0]; \ (m)[1][1] += (v)[1] * (t)[1]; \ (m)[1][2] += (v)[1] * (t)[2]; \ \ (m)[2][0] += (v)[2] * (t)[0]; \ (m)[2][1] += (v)[2] * (t)[1]; \ (m)[2][2] += (v)[2] * (t)[2]; \ } /* +========================================================== */ /* outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \ { \ (m)[0][0] += (v)[0] * (t)[0]; \ (m)[0][1] += (v)[0] * (t)[1]; \ (m)[0][2] += (v)[0] * (t)[2]; \ (m)[0][3] += (v)[0] * (t)[3]; \ \ (m)[1][0] += (v)[1] * (t)[0]; \ (m)[1][1] += (v)[1] * (t)[1]; \ (m)[1][2] += (v)[1] * (t)[2]; \ (m)[1][3] += (v)[1] * (t)[3]; \ \ (m)[2][0] += (v)[2] * (t)[0]; \ (m)[2][1] += (v)[2] * (t)[1]; \ (m)[2][2] += (v)[2] * (t)[2]; \ (m)[2][3] += (v)[2] * (t)[3]; \ \ (m)[3][0] += (v)[3] * (t)[0]; \ (m)[3][1] += (v)[3] * (t)[1]; \ (m)[3][2] += (v)[3] * (t)[2]; \ (m)[3][3] += (v)[3] * (t)[3]; \ } /* +========================================================== */ /* determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_2X2(d,m) \ { \ (d) = (m)[0][0] * (m)[1][1] - (m)[0][1] * (m)[1][0]; \ } /* ========================================================== */ /* determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_3X3(d,m) \ { \ (d) = (m)[0][0] * ((m)[1][1]*(m)[2][2] - (m)[1][2] * (m)[2][1]);\ (d) -= (m)[0][1] * ((m)[1][0]*(m)[2][2] - (m)[1][2] * (m)[2][0]);\ (d) += (m)[0][2] * ((m)[1][0]*(m)[2][1] - (m)[1][1] * (m)[2][0]);\ } /* ========================================================== */ /* i,j,th cofactor of a 4x4 matrix * */ #define COFACTOR_4X4_IJ(fac,m,i,j) \ { \ int ii[4], jj[4], k; \ \ /* compute which row, columnt to skip */ \ for (k=0; k<(i); k++) ii[k] = k; \ for (k=(i); k<3; k++) ii[k] = k+1; \ for (k=0; k<(j); k++) jj[k] = k; \ for (k=(j); k<3; k++) jj[k] = k+1; \ \ (fac) = (m)[ii[0]][jj[0]] * ((m)[ii[1]][jj[1]]*(m)[ii[2]][jj[2]] \ - (m)[ii[1]][jj[2]]*(m)[ii[2]][jj[1]]); \ (fac) -= (m)[ii[0]][jj[1]] * ((m)[ii[1]][jj[0]]*(m)[ii[2]][jj[2]] \ - (m)[ii[1]][jj[2]]*(m)[ii[2]][jj[0]]);\ (fac) += (m)[ii[0]][jj[2]] * ((m)[ii[1]][jj[0]]*(m)[ii[2]][jj[1]] \ - (m)[ii[1]][jj[1]]*(m)[ii[2]][jj[0]]);\ \ /* compute sign */ \ k = (i)+(j); \ if ( k != (k/2)*2) { \ (fac) = -(fac); \ } \ } /* ========================================================== */ /* determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_4X4(d,m) \ { \ double cofac; \ COFACTOR_4X4_IJ (cofac, (m), 0, 0); \ (d) = (m)[0][0] * cofac; \ COFACTOR_4X4_IJ (cofac, (m), 0, 1); \ (d) += (m)[0][1] * cofac; \ COFACTOR_4X4_IJ (cofac, (m), 0, 2); \ (d) += (m)[0][2] * cofac; \ COFACTOR_4X4_IJ (cofac, (m), 0, 3); \ (d) += (m)[0][3] * cofac; \ } /* ========================================================== */ /* cofactor of matrix * * Computes cofactor of matrix m, returning a */ #define COFACTOR_2X2(a,m) \ { \ (a)[0][0] = (m)[1][1]; \ (a)[0][1] = - (m)[1][0]; \ (a)[1][0] = - (m)[0][1]; \ (a)[1][1] = (m)[0][0]; \ } /* ========================================================== */ /* cofactor of matrix * * Computes cofactor of matrix m, returning a */ #define COFACTOR_3X3(a,m) \ { \ (a)[0][0] = (m)[1][1]*(m)[2][2] - (m)[1][2]*(m)[2][1]; \ (a)[0][1] = - ((m)[1][0]*(m)[2][2] - (m)[2][0]*(m)[1][2]); \ (a)[0][2] = (m)[1][0]*(m)[2][1] - (m)[1][1]*(m)[2][0]; \ (a)[1][0] = - ((m)[0][1]*(m)[2][2] - (m)[0][2]*(m)[2][1]); \ (a)[1][1] = (m)[0][0]*(m)[2][2] - (m)[0][2]*(m)[2][0]; \ (a)[1][2] = - ((m)[0][0]*(m)[2][1] - (m)[0][1]*(m)[2][0]); \ (a)[2][0] = (m)[0][1]*(m)[1][2] - (m)[0][2]*(m)[1][1]; \ (a)[2][1] = - ((m)[0][0]*(m)[1][2] - (m)[0][2]*(m)[1][0]); \ (a)[2][2] = (m)[0][0]*(m)[1][1] - (m)[0][1]*(m)[1][0]); \ } /* ========================================================== */ /* cofactor of matrix * * Computes cofactor of matrix m, returning a */ #define COFACTOR_4X4(a,m) \ { \ int i,j; \ \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ COFACTOR_4X4_IJ ((a)[i][j], (m), i, j); \ } \ } \ } /* ========================================================== */ /* adjoint of matrix * * Computes adjoint of matrix m, returning a * (Note that adjoint is just the transpose of the cofactor matrix) */ #define ADJOINT_2X2(a,m) \ { \ (a)[0][0] = (m)[1][1]; \ (a)[1][0] = - (m)[1][0]; \ (a)[0][1] = - (m)[0][1]; \ (a)[1][1] = (m)[0][0]; \ } /* ========================================================== */ /* adjoint of matrix * * Computes adjoint of matrix m, returning a * (Note that adjoint is just the transpose of the cofactor matrix) */ #define ADJOINT_3X3(a,m) \ { \ (a)[0][0] = (m)[1][1]*(m)[2][2] - (m)[1][2]*(m)[2][1]; \ (a)[1][0] = - ((m)[1][0]*(m)[2][2] - (m)[2][0]*(m)[1][2]); \ (a)[2][0] = (m)[1][0]*(m)[2][1] - (m)[1][1]*(m)[2][0]; \ (a)[0][1] = - ((m)[0][1]*(m)[2][2] - (m)[0][2]*(m)[2][1]); \ (a)[1][1] = (m)[0][0]*(m)[2][2] - (m)[0][2]*(m)[2][0]; \ (a)[2][1] = - ((m)[0][0]*(m)[2][1] - (m)[0][1]*(m)[2][0]); \ (a)[0][2] = (m)[0][1]*(m)[1][2] - (m)[0][2]*(m)[1][1]; \ (a)[1][2] = - ((m)[0][0]*(m)[1][2] - (m)[0][2]*(m)[1][0]); \ (a)[2][2] = (m)[0][0]*(m)[1][1] - (m)[0][1]*(m)[1][0]); \ } /* ========================================================== */ /* adjoint of matrix * * Computes adjoint of matrix m, returning a * (Note that adjoint is just the transpose of the cofactor matrix) */ #define ADJOINT_4X4(a,m) \ { \ int i,j; \ \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ COFACTOR_4X4_IJ ((a)[j][i], (m), i, j); \ } \ } \ } /* ========================================================== */ /* compute adjoint of matrix and scale * * Computes adjoint of matrix m, scales it by s, returning a */ #define SCALE_ADJOINT_2X2(a,s,m) \ { \ (a)[0][0] = s * (m)[1][1]; \ (a)[1][0] = - s * (m)[1][0]; \ (a)[0][1] = - s * (m)[0][1]; \ (a)[1][1] = s * (m)[0][0]; \ } /* ========================================================== */ /* compute adjoint of matrix and scale * * Computes adjoint of matrix m, scales it by s, returning a */ #define SCALE_ADJOINT_3X3(a,s,m) \ { \ (a)[0][0] = s * ((m)[1][1] * (m)[2][2] - (m)[1][2] * (m)[2][1]); \ (a)[1][0] = s * ((m)[1][2] * (m)[2][0] - (m)[1][0] * (m)[2][2]); \ (a)[2][0] = s * ((m)[1][0] * (m)[2][1] - (m)[1][1] * (m)[2][0]); \ \ (a)[0][1] = s * ((m)[0][2] * (m)[2][1] - (m)[0][1] * (m)[2][2]); \ (a)[1][1] = s * ((m)[0][0] * (m)[2][2] - (m)[0][2] * (m)[2][0]); \ (a)[2][1] = s * ((m)[0][1] * (m)[2][0] - (m)[0][0] * (m)[2][1]); \ \ (a)[0][2] = s * ((m)[0][1] * (m)[1][2] - (m)[0][2] * (m)[1][1]); \ (a)[1][2] = s * ((m)[0][2] * (m)[1][0] - (m)[0][0] * (m)[1][2]); \ (a)[2][2] = s * ((m)[0][0] * (m)[1][1] - (m)[0][1] * (m)[1][0]); \ } /* ========================================================== */ /* compute adjoint of matrix and scale * * Computes adjoint of matrix m, scales it by s, returning a */ #define SCALE_ADJOINT_4X4(a,s,m) \ { \ int i,j; \ \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ COFACTOR_4X4_IJ ((a)[j][i], (m), i, j); \ (a)[j][i] *= (s); \ } \ } \ } /* ========================================================== */ /* inverse of matrix * * Compute inverse of matrix a, returning determinant m and * inverse b */ #define INVERT_2X2(b,det,a) \ { \ double tmp; \ DETERMINANT_2X2 ((det), (a)); \ tmp = 1.0 / (det); \ SCALE_ADJOINT_2X2 ((b), tmp, (a)); \ } /* ========================================================== */ /* inverse of matrix * * Compute inverse of matrix a, returning determinant m and * inverse b */ #define INVERT_3X3(b,det,a) \ { \ double tmp; \ DETERMINANT_3X3 ((det), (a)); \ tmp = 1.0 / (det); \ SCALE_ADJOINT_3X3 ((b), tmp, (a)); \ } /* ========================================================== */ /* inverse of matrix * * Compute inverse of matrix a, returning determinant m and * inverse b */ #define INVERT_4X4(b,det,a) \ { \ double tmp; \ DETERMINANT_4X4 ((det), (a)); \ tmp = 1.0 / (det); \ SCALE_ADJOINT_4X4 ((b), tmp, (a)); \ } /* ========================================================== */ #if defined(__cplusplus) || defined(c_plusplus) }; #endif #endif /* __GUTIL_VECTOR_H__ */ /* ===================== END OF FILE ======================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/ex_raw.c0000644000175000017500000007177010061374075020237 0ustar debiandebian/* * MODULE NAME: ex_raw.c * * FUNCTION: * This module contains code that draws extrusions with square * ("raw join style") end styles. It also inserts colors and normals * where necessary, if appropriate. * * HISTORY: * written by Linas Vepstas August/September 1991 * split into multiple compile units, Linas, October 1991 * added normal vectors Linas, October 1991 * "code complete" (that is, I'm done), Linas Vepstas, October 1991 * work around OpenGL's lack of support for concave polys, June 1994 * * Copyright (C) 1991,1994,2003 Linas Vepstas */ #include #include #include #include /* for the memcpy() subroutine */ #include /* to get stderr defined */ #include "gle.h" #include "port.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" #include "segment.h" /* ============================================================ */ #ifndef COLOR_SIGNATURE /* * The following routine is, in principle, very simple: * all that it does is normalize the up vector, and makes * sure that it is perpendicular to the initial polyline segment. * * In fact, this routine gets awfully complicated because: * a) the first few segements of the polyline might be degenerate, * b) up vecotr may be parallel to first few segments of polyline, * c) etc. * */ void up_sanity_check (gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3]) /* polyline */ { int i; double len; double diff[3]; /* now, right off the bat, we should make sure that the up vector * is in fact perpendicular to the polyline direction */ VEC_DIFF (diff, point_array[1], point_array[0]); VEC_LENGTH (len, diff); if (len == 0.0) { /* This error message should go through an "official" error interface */ #ifndef WIN32 /* Win32 GUI programs do not have a valid error stream; and so * although they compile, they will crash when run. */ fprintf (stderr, "Extrusion: Warning: initial segment zero length \n"); #endif /* WIN32 */ /* loop till we find something that ain't of zero length */ for (i=1; i-1; j--) { point [0] = contour[j][0]; point [1] = contour[j][1]; V3F (point, j, BACK_CAP); } } ENDPOLYGON (); #endif /* GL_32 */ #ifdef OPENGL_10 /* malloc the @#$%^&* array that OpenGL wants ! */ pts = (double *) malloc (3*ncp*sizeof(double)); tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); gluBeginPolygon (tobj); /* draw the loop counter clockwise for the front cap */ if (frontwards) { for (j=0; j-1; j--) { pts [3*j] = contour[j][0]; pts [3*j+1] = contour[j][1]; pts [3*j+2] = zval; gluTessVertex (tobj, &pts[3*j], &pts[3*j]); } } gluEndPolygon (tobj); free (pts); gluDeleteTess (tobj); #endif /* OPENGL_10 */ } #endif /* COLOR_SIGNATURE */ /* ============================================================ */ /* This routine does what it says: It draws a counter-clockwise cap * from a 3D contour loop list */ static void draw_front_contour_cap (int ncp, /* number of contour points */ gleDouble contour[][3]) /* 3D contour */ { int j; #ifdef OPENGL_10 GLUtriangulatorObj *tobj; #endif /* OPENGL_10 */ #ifdef GL_32 /* old-style gl handles concave polygons no problem, so the code is * simple. New-style gl is a lot more tricky. */ /* draw the end cap */ BGNPOLYGON (); for (j=0; j-1; j--) { V3F (contour[j], j, BACK_CAP); } ENDPOLYGON (); #endif /* GL_32 */ #ifdef OPENGL_10 tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); gluBeginPolygon (tobj); /* draw the end cap */ /* draw the loop clockwise for the back cap */ /* the sense of the loop is reversed for backfacing culling */ for (j=ncp-1; j>-1; j--) { gluTessVertex (tobj, contour[j], contour[j]); } gluEndPolygon (tobj); gluDeleteTess (tobj); #endif /* OPENGL_10 */ } /* ============================================================ */ /* This routine draws a segment of raw-join-style tubing. * Essentially, we assume that the proper transformations have already * been performed to properly orient the tube segment -- our only task * left is to render */ /* PLAIN - NO COLOR, NO NORMAL */ static void draw_raw_segment_plain (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ int inext, gleDouble len) { int j; double point[3]; /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j */ #ifndef GLE_H__ #define GLE_H__ #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif /* some types */ #define __GLE_DOUBLE 1 #if __GLE_DOUBLE typedef double gleDouble; #else typedef float gleDouble; #endif typedef gleDouble gleAffine[2][3]; typedef float gleColor[3]; typedef float gleColor4f[4]; /* ====================================================== */ /* Defines for tubing join styles */ #define TUBE_JN_RAW 0x1 #define TUBE_JN_ANGLE 0x2 #define TUBE_JN_CUT 0x3 #define TUBE_JN_ROUND 0x4 #define TUBE_JN_MASK 0xf /* mask bits */ #define TUBE_JN_CAP 0x10 /* Determine how normal vectors are to be handled */ #define TUBE_NORM_FACET 0x100 #define TUBE_NORM_EDGE 0x200 #define TUBE_NORM_PATH_EDGE 0x400 /* for spiral, lathe, helix primitives */ #define TUBE_NORM_MASK 0xf00 /* mask bits */ /* Closed or open countours */ #define TUBE_CONTOUR_CLOSED 0x1000 #define GLE_TEXTURE_ENABLE 0x10000 #define GLE_TEXTURE_STYLE_MASK 0xff #define GLE_TEXTURE_VERTEX_FLAT 1 #define GLE_TEXTURE_NORMAL_FLAT 2 #define GLE_TEXTURE_VERTEX_CYL 3 #define GLE_TEXTURE_NORMAL_CYL 4 #define GLE_TEXTURE_VERTEX_SPH 5 #define GLE_TEXTURE_NORMAL_SPH 6 #define GLE_TEXTURE_VERTEX_MODEL_FLAT 7 #define GLE_TEXTURE_NORMAL_MODEL_FLAT 8 #define GLE_TEXTURE_VERTEX_MODEL_CYL 9 #define GLE_TEXTURE_NORMAL_MODEL_CYL 10 #define GLE_TEXTURE_VERTEX_MODEL_SPH 11 #define GLE_TEXTURE_NORMAL_MODEL_SPH 12 #ifdef GL_32 /* HACK for GL 3.2 -- needed because no way to tell if lighting is on. */ #define TUBE_LIGHTING_ON 0x80000000 #define gleExtrusion extrusion #define gleSetJoinStyle setjoinstyle #define gleGetJoinStyle getjoinstyle #define glePolyCone polycone #define glePolyCylinder polycylinder #define gleSuperExtrusion super_extrusion #define gleTwistExtrusion twist_extrusion #define gleSpiral spiral #define gleLathe lathe #define gleHelicoid helicoid #define gleToroid toroid #define gleScrew screw #endif /* GL_32 */ #ifdef _NO_PROTO /* NO ANSI C PROTOTYPING */ extern int gleGetJoinStyle (); extern void gleSetJoinStyle (); extern void glePolyCone (); extern void glePolyCylinder (); extern void gleExtrusion (); extern void gleSuperExtrusion (); extern void gleTwistExtrusion (); extern void gleSpiral (); extern void gleLathe (); extern void gleHelicoid (); extern void gleToroid (); extern void gleScrew (); /* Rotation Utilities */ extern void rot_axis (); extern void rot_about_axis (); extern void rot_omega (); extern void urot_axis (); extern void urot_about_axis (); extern void urot_omega (); /* viewpoint functions */ extern void uview_direction (); extern void uviewpoint (); #else /* _NO_PROTO */ /* ANSI C PROTOTYPING */ /* clean up global memory usage */ extern void gleDestroyGC (void); /* control join style of the tubes */ extern int gleGetJoinStyle (void); extern void gleSetJoinStyle (int style); /* bitwise OR of flags */ /* control number of sides used to draw cylinders, cones */ extern int gleGetNumSides(void); extern void gleSetNumSides(int slices); /* draw polyclinder, specified as a polyline */ extern void glePolyCylinder (int npoints, /* num points in polyline */ gleDouble point_array[][3], /* polyline vertces */ gleColor color_array[], /* colors at polyline verts */ gleDouble radius); /* radius of polycylinder */ extern void glePolyCylinder_c4f (int npoints, /* num points in polyline */ gleDouble point_array[][3], /* polyline vertces */ gleColor4f color_array[], /* colors at polyline verts */ gleDouble radius); /* radius of polycylinder */ /* draw polycone, specified as a polyline with radii */ extern void glePolyCone (int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor color_array[], /* colors at polyline verts */ gleDouble radius_array[]); /* cone radii at polyline verts */ extern void glePolyCone_c4f (int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor4f color_array[], /* colors at polyline verts */ gleDouble radius_array[]); /* cone radii at polyline verts */ /* extrude arbitrary 2D contour along arbitrary 3D path */ extern void gleExtrusion (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor color_array[]); /* colors at polyline verts */ extern void gleExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor4f color_array[]); /* colors at polyline verts */ /* extrude 2D contour, specifying local rotations (twists) */ extern void gleTwistExtrusion (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor color_array[], /* color at polyline verts */ gleDouble twist_array[]); /* countour twists (in degrees) */ extern void gleTwistExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor4f color_array[], /* color at polyline verts */ gleDouble twist_array[]); /* countour twists (in degrees) */ /* extrude 2D contour, specifying local affine tranformations */ extern void gleSuperExtrusion (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor color_array[], /* color at polyline verts */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void gleSuperExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline vertices */ gleColor4f color_array[], /* color at polyline verts */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ /* spiral moves contour along helical path by parallel transport */ extern void gleSpiral (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* lathe moves contour along helical path by helically shearing 3D space */ extern void gleLathe (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* similar to spiral, except contour is a circle */ extern void gleHelicoid (gleDouble rToroid, /* circle contour (torus) radius */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* similar to lathe, except contour is a circle */ extern void gleToroid (gleDouble rToroid, /* circle contour (torus) radius */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* draws a screw shape */ extern void gleScrew (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startz, /* start of segment */ gleDouble endz, /* end of segment */ gleDouble twist); /* number of rotations */ extern void gleTextureMode (int mode); /* Rotation Utilities */ extern void rot_axis (gleDouble omega, gleDouble axis[3]); extern void rot_about_axis (gleDouble angle, gleDouble axis[3]); extern void rot_omega (gleDouble axis[3]); extern void rot_prince (gleDouble omega, char axis); extern void urot_axis (gleDouble m[4][4], gleDouble omega, gleDouble axis[3]); extern void urot_about_axis (gleDouble m[4][4], gleDouble angle, gleDouble axis[3]); extern void urot_omega (gleDouble m[4][4], gleDouble axis[3]); extern void urot_prince (gleDouble m[4][4], gleDouble omega, char axis); /* viewpoint functions */ extern void uview_direction (gleDouble m[4][4], /* returned */ gleDouble v21[3], /* input */ gleDouble up[3]); /* input */ extern void uviewpoint (gleDouble m[4][4], /* returned */ gleDouble v1[3], /* input */ gleDouble v2[3], /* input */ gleDouble up[3]); /* input */ #endif /* _NO_PROTO */ #if defined(__cplusplus) || defined(c_plusplus) }; #endif #endif /* GLE_H__ */ /* ================== END OF FILE ======================= */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/rot_prince.c0000644000175000017500000001000410061374075021075 0ustar debiandebian #include #include "gle.h" #include "rot.h" #include "port.h" /* ========================================================== */ /* * The routines below generate and return more traditional rotation * matrices -- matrices for rotations about principal axes. */ /* ========================================================== */ static void urotx_cs (gleDouble m[4][4], /* returned */ gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create matrix that represents rotation about the x-axis */ ROTX_CS (m, cosine, sine); } /* ========================================================== */ static void rotx_cs (gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create and load matrix that represents rotation about the x-axis */ gleDouble m[4][4]; urotx_cs (m, cosine, sine); MULTMATRIX (m); } /* ========================================================== */ static void uroty_cs (gleDouble m[4][4], /* returned */ gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create matrix that represents rotation about the y-ayis */ ROTX_CS (m, cosine, sine); } /* ========================================================== */ static void roty_cs (gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create and load matriy that represents rotation about the y-ayis */ gleDouble m[4][4]; uroty_cs (m, cosine, sine); MULTMATRIX (m); } /* ========================================================== */ static void urotz_cs (gleDouble m[4][4], /* returned */ gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create matrix that represents rotation about the z-azis */ ROTX_CS (m, cosine, sine); } /* ========================================================== */ static void rotz_cs (gleDouble cosine, /* input */ gleDouble sine) /* input */ { /* create and load matrix that represents rotation about the z-azis */ gleDouble m[4][4]; urotz_cs (m, cosine, sine); MULTMATRIX (m); } /* ========================================================== */ static void urot_cs (gleDouble m[4][4], /* returned */ gleDouble cosine, /* input */ gleDouble sine, /* input */ char axis) /* input */ { /* create matrix that represents rotation about a principle axis */ switch (axis) { case 'x': case 'X': urotx_cs (m, cosine, sine); break; case 'y': case 'Y': uroty_cs (m, cosine, sine); break; case 'z': case 'Z': urotz_cs (m, cosine, sine); break; default: break; } } /* ========================================================== */ static void rot_cs (gleDouble cosine, /* input */ gleDouble sine, /* input */ char axis) /* input */ { /* create and load matrix that represents rotation about the z-axis */ gleDouble m[4][4]; urot_cs (m, cosine, sine, axis); MULTMATRIX (m); } /* ========================================================== */ void urot_prince (gleDouble m[4][4], /* returned */ gleDouble theta, /* input */ char axis) /* input */ { /* * generate rotation matrix for rotation around principal axis; * note that angle is measured in radians (divide by 180, multiply by * PI to convert from degrees). */ urot_cs (m, cos (theta), sin (theta), axis); } /* ========================================================== */ void rot_prince (gleDouble theta, /* input */ char axis) /* input */ { gleDouble m[4][4]; /* * generate rotation matrix for rotation around principal axis; * note that angle is measured in radians (divide by 180, multiply by * PI to convert from degrees). */ urot_prince (m, theta, axis); MULTMATRIX (m); } /* ========================================================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/qmesh.c0000644000175000017500000001265010061374075020057 0ustar debiandebian /* * This file contains routines to support the SGI compatible quad-mesh * primitve. These emulation routines are not required for OpenGL. * * Written By Linas Vepstas November 1991 */ #include #ifdef GL_32 struct _emu_qmesh_vertex_pair { float ca[3]; float na[3]; float va[4]; float cb[3]; float nb[3]; float vb[4]; }; #define QMESH 6 static int bgnmode = 0; struct _emu_qmesh { int num_vert; struct _emu_qmesh_vertex_pair paira; struct _emu_qmesh_vertex_pair pairb; struct _emu_qmesh_vertex_pair *first_pair; struct _emu_qmesh_vertex_pair *second_pair; float defer_color[3]; float defer_normal[3]; } * _emu_qmesh_GC; #define COPY_THREE_WORDS(A,B) { \ struct three_words { long a, b, c; }; \ *(struct three_words *) (A) = *(struct three_words *) (B); \ } #define COPY_FOUR_WORDS(A,B) { \ struct four_words { long a, b, c, d; }; \ *(struct four_words *) (A) = *(struct four_words *) (B); \ } /* ================================================================= */ void _emu_qmesh_InitGC (struct _emu_qmesh * tmp) { tmp -> num_vert = 0; tmp -> first_pair = & (tmp -> paira); tmp -> second_pair = & (tmp -> pairb); tmp -> defer_color[0] = 0.0; tmp -> defer_color[1] = 0.0; tmp -> defer_color[2] = 0.0; tmp -> defer_normal[0] = 0.0; tmp -> defer_normal[1] = 0.0; tmp -> defer_normal[2] = 0.0; } /* ================================================================= */ struct _emu_qmesh * _emu_qmesh_CreateGC (void) { struct _emu_qmesh * tmp; tmp = (struct _emu_qmesh *) malloc (sizeof (struct _emu_qmesh)); _emu_qmesh_InitGC (tmp); return (tmp); } /* ================================================================= */ void _emu_qmesh_DestroyGC (void) { free (_emu_qmesh_GC); } /* ================================================================= */ void _emu_qmesh_bgnqmesh (void) { _emu_qmesh_GC = _emu_qmesh_CreateGC (); bgnmode = QMESH; } /* ================================================================= */ void _emu_qmesh_endqmesh (void) { _emu_qmesh_DestroyGC (); bgnmode = 0; } /* ================================================================= */ void _emu_qmesh_c3f (float c[3]) { if (bgnmode == QMESH) { COPY_THREE_WORDS (_emu_qmesh_GC -> defer_color, c); } else { c3f (c); } } /* ================================================================= */ void _emu_qmesh_n3f (float n[3]) { if (bgnmode == QMESH) { COPY_THREE_WORDS (_emu_qmesh_GC -> defer_normal, n); } else { n3f (n); } } /* ================================================================= */ void _emu_qmesh_v3f (float v[3]) { int nv, even_odd, fs; struct _emu_qmesh_vertex_pair *tmp; if (bgnmode == QMESH) { nv = _emu_qmesh_GC -> num_vert; even_odd = nv %2; fs = (nv %4) / 2; if (fs) { if (even_odd) { COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.cb, _emu_qmesh_GC -> defer_color); COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.nb, _emu_qmesh_GC -> defer_normal); COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.vb, v); _emu_qmesh_GC -> pairb.vb [3] = 1.0; } else { COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.ca, _emu_qmesh_GC -> defer_color); COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.na, _emu_qmesh_GC -> defer_normal); COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.va, v); _emu_qmesh_GC -> pairb.va [3] = 1.0; } } else { if (even_odd) { COPY_THREE_WORDS (_emu_qmesh_GC -> paira.cb, _emu_qmesh_GC -> defer_color); COPY_THREE_WORDS (_emu_qmesh_GC -> paira.nb, _emu_qmesh_GC -> defer_normal); COPY_THREE_WORDS (_emu_qmesh_GC -> paira.vb, v); _emu_qmesh_GC -> paira.vb [3] = 1.0; } else { COPY_THREE_WORDS (_emu_qmesh_GC -> paira.ca, _emu_qmesh_GC -> defer_color); COPY_THREE_WORDS (_emu_qmesh_GC -> paira.na, _emu_qmesh_GC -> defer_normal); COPY_THREE_WORDS (_emu_qmesh_GC -> paira.va, v); _emu_qmesh_GC -> paira.va [3] = 1.0; } } if (even_odd && (nv >= 3)) { bgnpolygon (); c3f ( _emu_qmesh_GC -> first_pair -> ca); n3f ( _emu_qmesh_GC -> first_pair -> na); v4f ( _emu_qmesh_GC -> first_pair -> va); c3f ( _emu_qmesh_GC -> first_pair -> cb); n3f ( _emu_qmesh_GC -> first_pair -> nb); v4f ( _emu_qmesh_GC -> first_pair -> vb); c3f ( _emu_qmesh_GC -> second_pair -> cb); n3f ( _emu_qmesh_GC -> second_pair -> nb); v4f ( _emu_qmesh_GC -> second_pair -> vb); c3f ( _emu_qmesh_GC -> second_pair -> ca); n3f ( _emu_qmesh_GC -> second_pair -> na); v4f ( _emu_qmesh_GC -> second_pair -> va); endpolygon (); /* swap the data buffers */ tmp = _emu_qmesh_GC -> first_pair; _emu_qmesh_GC -> first_pair = _emu_qmesh_GC -> second_pair; _emu_qmesh_GC -> second_pair = tmp; } _emu_qmesh_GC -> num_vert ++; } else { v3f (v); } } #endif /* GL_32 */ /* ================================================================= */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/view.c0000644000175000017500000002107710061374075017717 0ustar debiandebian /* * MODULE Name: view.c * * FUNCTION: * This module provides two different routines that compute and return * viewing matrices. Both routines take a direction and an up vector, * and return a matrix that transforms the direction to the z-axis, and * the up-vector to the y-axis. * * HISTORY: * written by Linas Vepstas August 1991 * Added double precision interface, March 1993, Linas */ #include #include "gle.h" #include "rot.h" #include "vvector.h" /* ============================================================ */ /* * The uviewdirection subroutine computes and returns a 4x4 rotation * matrix that puts the negative z axis along the direction v21 and * puts the y axis along the up vector. * * Note that this code is fairly tolerant of "weird" paramters. * It normalizes when necessary, it does nothing when vectors are of * zero length, or are co-linear. This code shouldn't croak, no matter * what the user sends in as arguments. */ void uview_direction (gleDouble m[4][4], /* returned */ gleDouble v21[3], /* input */ gleDouble up[3]) /* input */ { gleDouble amat[4][4]; gleDouble bmat[4][4]; gleDouble cmat[4][4]; gleDouble v_hat_21[3]; gleDouble v_xy[3]; gleDouble sine, cosine; gleDouble len; gleDouble up_proj[3]; gleDouble tmp[3]; /* find the unit vector that points in the v21 direction */ VEC_COPY (v_hat_21, v21); VEC_LENGTH (len, v_hat_21); if (len != 0.0) { len = 1.0 / len; VEC_SCALE (v_hat_21, len, v_hat_21); /* rotate z in the xz-plane until same latitude */ sine = sqrt ( 1.0 - v_hat_21[2] * v_hat_21[2]); ROTY_CS (amat, (-v_hat_21[2]), (-sine)); } else { /* error condition: zero length vecotr passed in -- do nothing */ IDENTIFY_MATRIX_4X4 (amat); } /* project v21 onto the xy plane */ v_xy[0] = v21[0]; v_xy[1] = v21[1]; v_xy[2] = 0.0; VEC_LENGTH (len, v_xy); /* rotate in the x-y plane until v21 lies on z axis --- * but of course, if its already there, do nothing */ if (len != 0.0) { /* want xy projection to be unit vector, so that sines/cosines pop out */ len = 1.0 / len; VEC_SCALE (v_xy, len, v_xy); /* rotate the projection of v21 in the xy-plane over to the x axis */ ROTZ_CS (bmat, v_xy[0], v_xy[1]); /* concatenate these together */ MATRIX_PRODUCT_4X4 (cmat, amat, bmat); } else { /* no-op -- vector is already in correct position */ COPY_MATRIX_4X4 (cmat, amat); } /* up vector really should be perpendicular to the x-form direction -- * Use up a couple of cycles, and make sure it is, * just in case the user blew it. */ VEC_PERP (up_proj, up, v_hat_21); VEC_LENGTH (len, up_proj); if (len != 0.0) { /* normalize the vector */ len = 1.0/len; VEC_SCALE (up_proj, len, up_proj); /* compare the up-vector to the y-axis to get the cosine of the angle */ tmp [0] = cmat [1][0]; tmp [1] = cmat [1][1]; tmp [2] = cmat [1][2]; VEC_DOT_PRODUCT (cosine, tmp, up_proj); /* compare the up-vector to the x-axis to get the sine of the angle */ tmp [0] = cmat [0][0]; tmp [1] = cmat [0][1]; tmp [2] = cmat [0][2]; VEC_DOT_PRODUCT (sine, tmp, up_proj); /* rotate to align the up vector with the y-axis */ ROTZ_CS (amat, cosine, -sine); /* This xform, although computed last, acts first */ MATRIX_PRODUCT_4X4 (m, amat, cmat); } else { /* error condition: up vector is indeterminate (zero length) * -- do nothing */ COPY_MATRIX_4X4 (m, cmat); } } /* ============================================================ */ #ifdef __STALE_CODE /* * The uview_dire subroutine computes and returns a 4x4 rotation * matrix that puts the negative z axis along the direction v21 and * puts the y axis along the up vector. * * It computes exactly the same matrix as the code above * (uview_direction), but with an entirely different (and slower) * algorithm. * * Note that the code below is slightly less robust than that above -- * it may croak if the supplied vectors are of zero length, or are * parallel to each other ... */ void uview_dire (float m[4][4], /* returned */ float v21[3], /* input */ float up[3]) /* input */ { gleDouble theta; float v_hat_21 [3]; float z_hat [3]; float v_cross_z [3]; float u[3]; float y_hat [3]; float u_cross_y [3]; gleDouble cosine; float zmat [4][4]; float upmat[4][4]; float dot; /* perform rotation to z-axis only if not already * pointing down z */ if ((v21[0] != 0.0 ) || (v21[1] != 0.0)) { /* find the unit vector that points in the v21 direction */ VEC_COPY (v_hat_21, v21); VEC_NORMALIZE (v_hat_21); /* cosine theta equals v_hat dot z_hat */ cosine = - v_hat_21 [2]; theta = - acos (cosine); /* Take cros product with z -- we need this, because we will rotate * about this axis */ z_hat[0] = 0.0; z_hat[1] = 0.0; z_hat[2] = -1.0; VEC_CROSS_PRODUCT (v_cross_z, v_hat_21, z_hat); VEC_NORMALIZE (v_cross_z); /* compute rotation matrix that takes -z axis to the v21 axis */ urot_axis (zmat, (float) theta, v_cross_z); } else { IDENTIFY_MATRIX_4X4 (zmat); if (v21[2] > 0.0) { /* if its pointing down the positive z-axis, flip it, so that * we point down negative z-axis. We flip x so that the partiy * isn't destroyed (looks like a rotation) */ zmat[0][0] = -1.0; zmat[2][2] = -1.0; } } /* --------------------- */ /* OK, now compute the part that takes the y-axis to the up vector */ VEC_COPY (u, up); /* the rotation blows up, if the up vector is not perpendicular to * the v21 vector. Let us make sure that this is so. */ VEC_PERP (u, u, v_hat_21); /* need to run the y axis through above x-form, to see where it went */ y_hat[0] = zmat [1][0]; y_hat[1] = zmat [1][1]; y_hat[2] = zmat [1][2]; /* perform rotation to up-axis only if not already * pointing along y axis */ VEC_DOT_PRODUCT (dot, y_hat, u); if ((-1.0 < dot) && (dot < 1.0)) { /* make sure that up really is a unit vector */ VEC_NORMALIZE (u); /* cosine phi equals y_hat dot up_vec */ VEC_DOT_PRODUCT (cosine, u, y_hat); theta = - acos (cosine); /* Take cross product with y */ VEC_CROSS_PRODUCT (u_cross_y, u, y_hat); VEC_NORMALIZE (u_cross_y); /* As a matter of fact, u_cross_y points either in the v21 direction, * or in the minus v21 direction. In either case, we needed to compute * it, because the the arccosine function returns values only for * 0 to 180 degree, not 0 to 360, which is what we need. The * cross-product helps us make up for this. */ /* rotate about the NEW z axis (i.e. v21) by the cosine */ urot_axis (upmat, (float) theta, u_cross_y); } else { IDENTIFY_MATRIX_4X4 (upmat); if (dot == -1.0) { /* if its pointing along the negative y-axis, flip it, so that * we point along the positive y-axis. We flip x so that the partiy * isn't destroyed (looks like a rotation) */ upmat[0][0] = -1.0; upmat[1][1] = -1.0; } } MATRIX_PRODUCT_4X4 (m, zmat, upmat); } #endif /* __STALE_CODE */ /* ============================================================ */ /* * The uviewpoint subroutine computes and returns a 4x4 matrix that * translates the origen to the point v1, puts the negative z axis * along the direction v21==v2-v1, and puts the y axis along the up * vector. */ void uviewpoint (gleDouble m[4][4], /* returned */ gleDouble v1[3], /* input */ gleDouble v2[3], /* input */ gleDouble up[3]) /* input */ { gleDouble v_hat_21 [3]; gleDouble trans_mat[4][4]; gleDouble rot_mat[4][4]; /* find the vector that points in the v21 direction */ VEC_DIFF (v_hat_21, v2, v1); /* compute rotation matrix that takes -z axis to the v21 axis, * and y to the up dierction */ uview_direction (rot_mat, v_hat_21, up); /* build matrix that translates the origin to v1 */ IDENTIFY_MATRIX_4X4 (trans_mat); trans_mat[3][0] = v1[0]; trans_mat[3][1] = v1[1]; trans_mat[3][2] = v1[2]; /* concatenate the matrices together */ MATRIX_PRODUCT_4X4 (m, rot_mat, trans_mat); } /* ================== END OF FILE ============================ */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/port.h0000644000175000017500000001654310122107254017727 0ustar debiandebian /* * port.h * * FUNCTION: * This file contains defines for porting the tubing toolkit * from GL to OpenGL; it also allows one to define an interface * to get at the low-level GL output of this package via callbacks. * * HISTORY: * Created by Linas Vepstas -- February 1993 * Added auto texture coord generation hooks, Linas April 1994 */ #ifndef __GLE_PORT_H__ #define __GLE_PORT_H__ #include /* most of the build-specific info should be in configure.in */ #include "../config.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* ====================================================== */ /* needed for Windows NT */ #ifdef WIN32 #include #endif /* ====================================================== */ /* Some compilers can't handle multiply-subscripted array's */ #if FUNKY_C typedef gleDouble gleVector; #define AVAL(arr,n,i,j) arr(6*n+3*i+j) #define VVAL(arr,n,i) arr(3*n+i) #else /* FUNKY_C */ typedef double gleVector[3]; #define AVAL(arr,n,i,j) arr[n][i][j] #define VVAL(arr,n,i) arr[n][i]; #endif /* FUNKY_C */ /* ====================================================== */ /* These are used to convey info about topography to the * texture mapping routines */ #define FRONT 1 #define BACK 2 #define FRONT_CAP 3 #define BACK_CAP 4 #define FILLET 5 /* ====================================================== */ #ifdef __GLE_DOUBLE /* #define gleDouble double */ #define MULTMATRIX(m) MULTMATRIX_D(m) #define LOADMATRIX(m) LOADMATRIX_D(m) #define V3F(x,j,id) V3F_D(x,j,id) #define N3F(x) N3F_D(x) #define T2F(x,y) T2F_D(x,y) #else #define gleDouble float #define MULTMATRIX(m) MULTMATRIX_F(m) #define LOADMATRIX(m) LOADMATRIX_F(m) #define V3F(x,j,id) V3F_F(x,j,id) #define N3F(x) N3F_F(x) #define T2F(x,y) T2F_F(x,y) #endif /* ====================================================== */ #if DEBUG_OUTPUT #undef GL_32 #undef OPENGL_10 #define BGNTMESH(i,len) printf ("bgntmesh() \n"); #define ENDTMESH() printf ("endtmesh() \n"); #define BGNPOLYGON() printf ("bgnpolygon() \n"); #define ENDPOLYGON() printf ("endpolygon() \n"); #define V3F_F(x,j,id) printf ("v3f(x) %f %f %f \n", x[0], x[1], x[2]); #define V3F_D(x,j,id) printf ("v3d(x) %f %f %f \n", x[0], x[1], x[2]); #define N3F_F(x) printf ("n3f(x) %f %f %f \n", x[0], x[1], x[2]); #define N3F_D(x) printf ("n3d(x) %f %f %f \n", x[0], x[1], x[2]); #define C3F(x) printf ("c3f(x) %f %f %f \n", x[0], x[1], x[2]); #define T2F_F(x) printf ("t2f(x) %f %f \n", x[0], x[1]); #define T2F_D(x) printf ("t2d(x) %f %f \n", x[0], x[1]); #define POPMATRIX() printf ("popmatrix () \n"); #define PUSHMATRIX() printf ("pushmatrix() \n"); #define MULTMATRIX_F(x) MULTMATRIX_D(x) #define LOADMATRIX_F(x) LOADMATRIX_D(x) #define LOADMATRIX_D(x) { \ int i, j; \ printf ("loadmatrix (x) \n"); \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ printf ( "%f ", (x)[i][j]); \ } \ printf (" \n"); \ } \ } #define MULTMATRIX_D(x) { \ int i, j; \ printf ("multmatrix (x) \n"); \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ printf ( "%f ", (x)[i][j]); \ } \ printf (" \n"); \ } \ } #define __IS_LIGHTING_ON (1) #endif /* DEBUG_OUTPUT */ /* ====================================================== */ #if GL_32 #ifdef __APPLE__ #include #else #include #endif #define BGNTMESH(i,len) bgntmesh() #define ENDTMESH() endtmesh() #define BGNPOLYGON() bgnpolygon() #define ENDPOLYGON() endpolygon() #define V3F_F(x,j,id) v3f(x) #define V3F_D(x,j,id) v3d(x) #define N3F_F(x) n3f(x) #define T2F_F(x,y) #define T2F_D(x,y) #define C3F(x) c3f(x) #define POPMATRIX() popmatrix () #define PUSHMATRIX() pushmatrix() #define MULTMATRIX_F(x) multmatrix (x) #define LOADMATRIX_F(x) loadmatrix (x) #define N3F_D(x) { \ float nnn[3]; \ nnn[0] = (float) (x)[0]; \ nnn[1] = (float) (x)[1]; \ nnn[2] = (float) (x)[2]; \ n3f (nnn); \ } #define LOADMATRIX_D(x) { \ int i, j; \ float mmm[4][4]; \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ mmm[i][j] = (float) (x)[i][j]; \ } \ } \ loadmatrix(mmm); \ } #define MULTMATRIX_D(x) { \ int i, j; \ float mmm[4][4]; \ for (i=0; i<4; i++) { \ for (j=0; j<4; j++) { \ mmm[i][j] = (float) (x)[i][j]; \ } \ } \ multmatrix(mmm); \ } /* #define __IS_LIGHTING_ON (MSINGLE == getmmode()) */ #define __IS_LIGHTING_ON (extrusion_join_style & TUBE_LIGHTING_ON) #endif /* GL_32 */ /* ====================================================== */ #if OPENGL_10 #ifdef WIN32 #include #endif #ifdef __APPLE__ #include #include #else #include #include #endif #if FLIP_NORMAL #define N3F_F(x) { \ float nnn[3]; \ nnn[0] = - (float) (x)[0]; \ nnn[1] = - (float) (x)[1]; \ nnn[2] = - (float) (x)[2]; \ glNormal3fv (nnn); \ } #define N3F_D(x) { \ float nnn[3]; \ nnn[0] = - (float) (x)[0]; \ nnn[1] = - (float) (x)[1]; \ nnn[2] = - (float) (x)[2]; \ glNormal3fv (nnn); \ } #endif /* FLIP_NORMAL */ #define C3F(x) glColor3fv(x) #define T2F_F(x,y) glTexCoord2f(x,y) #define T2F_D(x,y) glTexCoord2d(x,y) #define POPMATRIX() glPopMatrix() #define PUSHMATRIX() glPushMatrix() #define MULTMATRIX_F(x) glMultMatrixf ((const GLfloat *)x) #define LOADMATRIX_F(x) glLoadMatrixf ((const GLfloat *)x) #define MULTMATRIX_D(x) glMultMatrixd ((const GLdouble *)x) #define LOADMATRIX_D(x) glLoadMatrixd ((const GLdouble *)x) #define __IS_LIGHTING_ON (glIsEnabled(GL_LIGHTING)) /* ====================================================== */ #ifdef AUTO_TEXTURE #define BGNTMESH(i,len) { \ if(_gle_gc -> bgn_gen_texture) (*(_gle_gc -> bgn_gen_texture))(i,len);\ glBegin (GL_TRIANGLE_STRIP); \ } #define BGNPOLYGON() { \ if(_gle_gc -> bgn_gen_texture) (*(_gle_gc -> bgn_gen_texture))();\ glBegin (GL_POLYGON); \ } #define N3F_F(x) { \ if(_gle_gc -> n3f_gen_texture) (*(_gle_gc -> n3f_gen_texture))(x); \ glNormal3fv(x); \ } #define N3F_D(x) { \ if(_gle_gc -> n3d_gen_texture) (*(_gle_gc -> n3d_gen_texture))(x); \ glNormal3dv(x); \ } #define V3F_F(x,j,id) { \ if(_gle_gc -> v3f_gen_texture) (*(_gle_gc -> v3f_gen_texture))(x,j,id);\ glVertex3fv(x); \ } #define V3F_D(x,j,id) { \ if(_gle_gc -> v3d_gen_texture) (*(_gle_gc -> v3d_gen_texture))(x,j,id); \ glVertex3dv(x); \ } #define ENDTMESH() { \ if(_gle_gc -> end_gen_texture) (*(_gle_gc -> end_gen_texture))(); \ glEnd (); \ } #define ENDPOLYGON() { \ if(_gle_gc -> end_gen_texture) (*(_gle_gc -> end_gen_texture))(); \ glEnd (); \ } /* ====================================================== */ #else /* AUTO_TEXTURE */ #define BGNTMESH(i,len) glBegin (GL_TRIANGLE_STRIP); #define BGNPOLYGON() glBegin (GL_POLYGON); #define N3F_F(x) glNormal3fv(x) #define N3F_D(x) glNormal3dv(x) #define V3F_F(x,j,id) glVertex3fv(x); #define V3F_D(x,j,id) glVertex3dv(x); #define ENDTMESH() glEnd () #define ENDPOLYGON() glEnd() #endif /* AUTO_TEXTURE */ #endif /* OPENGL_10 */ #endif /* __GLE_PORT_H__ */ /* ================== END OF FILE ======================= */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/urotate.c0000644000175000017500000001261710061374075020430 0ustar debiandebian /* * MODULE: urotate.c * * FUNCTION: * This module contains three different routines that compute rotation * matricies and return these to user. * Detailed description is provided below. * * HISTORY: * Developed & written, Linas Vepstas, Septmeber 1991 * double precision port, March 1993 * * DETAILED DESCRIPTION: * This module contains three routines: * -------------------------------------------------------------------- * * void urot_about_axis (float m[4][4], --- returned * float angle, --- input * float axis[3]) --- input * Computes a rotation matrix. * The rotation is around the the direction specified by the argument * argument axis[3]. User may specify vector which is not of unit * length. The angle of rotation is specified in degrees, and is in the * right-handed direction. * * void rot_about_axis (float angle, --- input * float axis[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- * * void urot_axis (float m[4][4], --- returned * float omega, --- input * float axis[3]) --- input * Same as urot_about_axis(), but angle specified in radians. * It is assumed that the argument axis[3] is a vector of unit length. * If it is not of unit length, the returned matrix will not be correct. * * void rot_axis (float omega, --- input * float axis[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- * * void urot_omega (float m[4][4], --- returned * float omega[3]) --- input * same as urot_axis(), but the angle is taken as the length of the * vector omega[3] * * void rot_omega (float omega[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- */ #include #include "gle.h" #include "port.h" /* ========================================================== */ void urot_axis (gleDouble m[4][4], /* returned */ gleDouble omega, /* input */ gleDouble axis[3]) /* input */ { gleDouble s, c, ssq, csq, cts; gleDouble tmp; /* * The formula coded up below can be derived by using the * homomorphism between SU(2) and O(3), namely, that the * 3x3 rotation matrix R is given by * t.R.v = S(-1) t.v S * where * t are the Pauli matrices (similar to Quaternions, easier to use) * v is an arbitrary 3-vector * and S is a 2x2 hermitian matrix: * S = exp ( i omega t.axis / 2 ) * * (Also, remember that computer graphics uses the transpose of R). * * The Pauli matrices are: * * tx = (0 1) ty = (0 -i) tz = (1 0) * (1 0) (i 0) (0 -1) * * Note that no error checking is done -- if the axis vector is not * of unit length, you'll get strange results. */ tmp = (double) omega / 2.0; s = sin (tmp); c = cos (tmp); ssq = s*s; csq = c*c; m[0][0] = m[1][1] = m[2][2] = csq - ssq; ssq *= 2.0; /* on-diagonal entries */ m[0][0] += ssq * axis[0]*axis[0]; m[1][1] += ssq * axis[1]*axis[1]; m[2][2] += ssq * axis[2]*axis[2]; /* off-diagonal entries */ m[0][1] = m[1][0] = axis[0] * axis[1] * ssq; m[1][2] = m[2][1] = axis[1] * axis[2] * ssq; m[2][0] = m[0][2] = axis[2] * axis[0] * ssq; cts = 2.0 * c * s; tmp = cts * axis[2]; m[0][1] += tmp; m[1][0] -= tmp; tmp = cts * axis[0]; m[1][2] += tmp; m[2][1] -= tmp; tmp = cts * axis[1]; m[2][0] += tmp; m[0][2] -= tmp; /* homogeneous entries */ m[0][3] = m[1][3] = m[2][3] = m[3][2] = m[3][1] = m[3][0] = 0.0; m[3][3] = 1.0; } /* ========================================================== */ void urot_about_axis (gleDouble m[4][4], /* returned */ gleDouble angle, /* input */ gleDouble axis[3]) /* input */ { gleDouble len, ax[3]; angle *= M_PI/180.0; /* convert to radians */ /* renormalize axis vector, if needed */ len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; /* we can save some machine instructions by normalizing only * if needed. The compiler should be able to schedule in the * if test "for free". */ if (len != 1.0) { len = (gleDouble) (1.0 / sqrt ((double) len)); ax[0] = axis[0] * len; ax[1] = axis[1] * len; ax[2] = axis[2] * len; urot_axis (m, angle, ax); } else { urot_axis (m, angle, axis); } } /* ========================================================== */ void urot_omega (gleDouble m[4][4], /* returned */ gleDouble axis[3]) /* input */ { gleDouble len, ax[3]; /* normalize axis vector */ len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; len = (gleDouble) (1.0 / sqrt ((double) len)); ax[0] = axis[0] * len; ax[1] = axis[1] * len; ax[2] = axis[2] * len; /* the amount of rotation is equal to the length, in radians */ urot_axis (m, len, ax); } /* ======================= END OF FILE ========================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/round_cap.c0000644000175000017500000001444310061374075020716 0ustar debiandebian/* * MODULE NAME: round_cap.c * * FUNCTION: * This module contains code that draws the round end-cap for round * join-style tubing. * * HISTORY: * written by Linas Vepstas August/September 1991 * split into multiple compile units, Linas, October 1991 * added normal vectors Linas, October 1991 */ #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "vvector.h" #include "extrude.h" #include "tube_gc.h" #include "intersect.h" #include "segment.h" /* ============================================================ */ /* This routine does what it says: It draws the end-caps for the * "round" join style. */ /* HACK ALERT HACK ALERT HACK ALERT HACK ALERT */ /* This #define should be replaced by some adaptive thingy. * the adaptiveness needs to depend on relative angles and diameter of * extrusion relative to screen size (in pixels). */ #define __ROUND_TESS_PIECES 5 void draw_round_style_cap_callback (int ncp, double cap[][3], gleColor face_color, gleDouble cut[3], gleDouble bi[3], double norms[][3], int frontwards) { double axis[3]; double xycut[3]; double theta; double *last_contour, *next_contour; double *last_norm, *next_norm; double *cap_z; double *tmp; char *malloced_area; int i, j, k; double m[4][4]; if (face_color != NULL) C3F (face_color); /* ------------ start setting up rotation matrix ------------- */ /* if the cut vector is NULL (this should only occur in * a degenerate case), then we can't draw anything. return. */ if (cut == NULL) return; /* make sure that the cut vector points inwards */ if (cut[2] > 0.0) { VEC_SCALE (cut, -1.0, cut); } /* make sure that the bi vector points outwards */ if (bi[2] < 0.0) { VEC_SCALE (bi, -1.0, bi); } /* determine the axis we are to rotate about to get bi-contour. * Note that the axis will always lie in the x-y plane */ VEC_CROSS_PRODUCT (axis, cut, bi); /* reverse the cut vector for the back cap -- * need to do this to get angle right */ if (!frontwards) { VEC_SCALE (cut, -1.0, cut); } /* get angle to rotate by -- arccos of dot product of cut with cut * projected into the x-y plane */ xycut [0] = 0.0; xycut [1] = 0.0; xycut [2] = 1.0; VEC_PERP (xycut, cut, xycut); VEC_NORMALIZE (xycut); VEC_DOT_PRODUCT (theta, xycut, cut); theta = acos (theta); /* we'll tesselate round joins into a number of teeny pieces */ theta /= (double) __ROUND_TESS_PIECES; /* get the matrix */ urot_axis (m, theta, axis); /* ------------ done setting up rotation matrix ------------- */ /* This malloc is a fancy version of: * last_contour = (double *) malloc (3*ncp*sizeof(double); * next_contour = (double *) malloc (3*ncp*sizeof(double); */ malloced_area = malloc ((4*3+1) *ncp*sizeof (double)); last_contour = (double *) malloced_area; next_contour = last_contour + 3*ncp; cap_z = next_contour + 3*ncp; last_norm = cap_z + ncp; next_norm = last_norm + 3*ncp; /* make first copy of contour */ if (frontwards) { for (j=0; j */ /* ============================================================ */ extern void draw_segment_plain (int ncp, /* number of contour points */ gleVector front_contour[], gleVector back_contour[], int inext, double len); extern void draw_segment_color (int ncp, /* number of contour points */ gleVector front_contour[], gleVector back_contour[], gleColor color_last, gleColor color_next, int inext, double len); extern void draw_segment_color_c4f (int ncp, /* number of contour points */ gleVector front_contour[], gleVector back_contour[], gleColor4f color_last, gleColor4f color_next, int inext, double len); extern void draw_segment_edge_n (int ncp, /* number of contour points */ gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], int inext, double len); extern void draw_segment_c_and_edge_n (int ncp, gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], gleColor color_last, gleColor color_next, int inext, double len); extern void draw_segment_c_and_edge_n_c4f (int ncp, gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], gleColor4f color_last, gleColor4f color_next, int inext, double len); extern void draw_segment_facet_n (int ncp, gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], int inext, double len); extern void draw_segment_c_and_facet_n (int ncp, gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], gleColor color_last, gleColor color_next, int inext, double len); extern void draw_segment_c_and_facet_n_c4f (int ncp, gleVector front_contour[], gleVector back_contour[], double norm_cont[][3], gleColor4f color_last, gleColor4f color_next, int inext, double len); /* ============================================================ */ extern void draw_binorm_segment_edge_n (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], int inext, double len); extern void draw_binorm_segment_c_and_edge_n (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], gleColor color_last, gleColor color_next, int inext, double len); extern void draw_binorm_segment_c_and_edge_n_c4f (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], gleColor4f color_last, gleColor4f color_next, int inext, double len); extern void draw_binorm_segment_facet_n (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], int inext, double len); extern void draw_binorm_segment_c_and_facet_n (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], gleColor color_last, gleColor color_next, int inext, double len); extern void draw_binorm_segment_c_and_facet_n_c4f (int ncp, double front_contour[][3], double back_contour[][3], double front_norm[][3], double back_norm[][3], gleColor4f color_last, gleColor4f color_next, int inext, double len); extern void draw_angle_style_front_cap (int ncp, /* num of contour pts */ gleDouble bi[3], /* biscetor */ gleVector point_array[]); /* polyline */ extern void draw_angle_style_back_cap (int ncp, /* num of contour pts */ gleDouble bi[3], /* biscetor */ gleVector point_array[]); /* polyline */ /* -------------------------- end of file -------------------------------- */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/intersect.c0000644000175000017500000000437610061374075020750 0ustar debiandebian/* * FUNCTION: * This file contains a number of utilities useful to 3D graphics in * general, and to the generation of tubing and extrusions in particular * * HISTORY: * Written by Linas Vepstas, August 1991 */ #include "gle.h" #include "intersect.h" /* ========================================================== */ /* * The macro and subroutine INTERSECT are designed to compute the * intersection of a line (defined by the points v1 and v2) and a plane * (defined as plane which is normal to the vector n, and contains the * point p). Both sect the array "sect", which is the point of * interesection. * * The subroutine returns a value indicating if the specified inputs * represented a degenerate case. Valid is TRUE if the computed * intersection is valid, else it is FALSE. */ /* ========================================================== */ int intersect (gleDouble sect[3], /* returned */ gleDouble p[3], /* input */ gleDouble n[3], /* input */ gleDouble v1[3], /* input */ gleDouble v2[3]) /* input */ { int valid; INTERSECT (valid, sect, p, n, v1, v2); return (valid); } /* ========================================================== */ /* * The macro and subroutine BISECTING_PLANE compute a normal vecotr that * describes the bisecting plane between three points (v1, v2 and v3). * This bisecting plane has the following properties: * 1) it contains the point v2 * 2) the angle it makes with v21 == v2 - v1 is equal to the angle it * makes with v32 == v3 - v2 * 3) it is perpendicular to the plane defined by v1, v2, v3. * * Having input v1, v2, and v3, it returns a vector n. * Note that n is NOT normalized (is NOT of unit length). * * The subroutine returns a value indicating if the specified inputs * represented a degenerate case. Valid is TRUE if the computed * intersection is valid, else it is FALSE. */ int bisecting_plane (gleDouble n[3], /* returned */ gleDouble v1[3], /* input */ gleDouble v2[3], /* input */ gleDouble v3[3]) /* input */ { int valid; BISECTING_PLANE (valid, n, v1, v2, v3); return (valid); } /* ========================================================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/extrude.h0000644000175000017500000001363010061374075020426 0ustar debiandebian/* * FILE: * extrude.h * * FUNCTION: * Prototypes for privately used subroutines for the tubing library. * Applications should not include this file. * * HISTORY: * Copyright (C) 1991,2003 Linas Vepstas */ #ifndef GLE_EXTRUDE_H_ #define GLE_EXTRUDE_H_ /* ============================================================ */ /* * Provides choice of calling subroutine, vs. invoking macro. * Basically, inlines the source, or not. * Trades performance for executable size. */ #define INLINE_INTERSECT #ifdef INLINE_INTERSECT #define INNERSECT(sect,p,n,v1,v2) { int retval; INTERSECT(retval,sect,p,n,v1,v2); } #else #define INNERSECT(sect,p,n,v1,v2) intersect(sect,p,n,v1,v2) #endif /* INLINE_INTERSECT */ /* ============================================================ */ /* The folowing defines give a kludgy way of accessing the qmesh primitive */ /* #define bgntmesh _emu_qmesh_bgnqmesh #define endtmesh _emu_qmesh_endqmesh #define c3f _emu_qmesh_c3f #define n3f _emu_qmesh_n3f #define v3f _emu_qmesh_v3f */ /* ============================================================ */ /* Mid-level drawing routines. Note that some of these differ * only due to the different color array argument */ extern void up_sanity_check (gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3]); /* polyline */ extern void draw_raw_style_end_cap (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble zval, /* where to draw cap */ int frontwards); /* front or back cap */ extern void draw_round_style_cap_callback (int iloop, double cap[][3], gleColor face_color, gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards); extern void draw_round_style_cap_callback_c4f (int iloop, double cap[][3], gleColor4f face_color, gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards); extern void extrusion_raw_join (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void extrusion_raw_join_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor4f color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void extrusion_round_or_cut_join (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void extrusion_round_or_cut_join_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor4f color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void extrusion_angle_join (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ extern void extrusion_angle_join_c4f (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D contour normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor4f color_array[], /* color of polyline */ gleDouble xform_array[][2][3]); /* 2D contour xforms */ #endif /* GLE_EXTRUDE_H_ */ /* -------------------------- end of file -------------------------------- */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/ex_alpha.c0000644000175000017500000000377010061374075020526 0ustar debiandebian/* * FILE: * ex_alpha.c * * FUNCTION: * Framework file to auto-generate subroutines with different * signature for color argument. The *_c4f routines take a * 3D RGBA color so that alpha transparency can be supported. * * HISTORY: * Copyright (c) 2003 Linas Vepstas */ #include "config.h" #include "gle.h" #include "port.h" /* Autogen the missing c4f routines by redefining C3F to be 4F, * changeing the subroutine signature, and changing the function names. */ #undef C3F #define C3F(x) glColor4fv(x) #define gleColor gleColor4f #define COLOR_SIGNATURE 1 #define draw_raw_segment_color draw_raw_segment_color_c4f #define draw_raw_segment_c_and_edge_n draw_raw_segment_c_and_edge_n_c4f #define draw_raw_segment_c_and_facet_n draw_raw_segment_c_and_facet_n_c4f #define draw_round_style_cap_callback draw_round_style_cap_callback_c4f #define draw_segment_color draw_segment_color_c4f #define draw_segment_c_and_edge_n draw_segment_c_and_edge_n_c4f #define draw_segment_c_and_facet_n draw_segment_c_and_facet_n_c4f #define draw_binorm_segment_c_and_edge_n draw_binorm_segment_c_and_edge_n_c4f #define draw_binorm_segment_c_and_facet_n draw_binorm_segment_c_and_facet_n_c4f #define extrusion_raw_join extrusion_raw_join_c4f #define extrusion_angle_join extrusion_angle_join_c4f #define extrusion_round_or_cut_join extrusion_round_or_cut_join_c4f #define gen_polycone gen_polycone_c4f #define gleSuperExtrusion gleSuperExtrusion_c4f #define gleExtrusion gleExtrusion_c4f #define glePolyCylinder glePolyCylinder_c4f #define glePolyCone glePolyCone_c4f #define gleTwistExtrusion gleTwistExtrusion_c4f /* Now include the source files ! */ #include "ex_angle.c" #include "ex_cut_round.c" #include "ex_raw.c" #include "extrude.c" #include "round_cap.c" #include "segment.c" /* ===================== END OF FILE ======================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/rotate.c0000644000175000017500000000575010061374075020243 0ustar debiandebian/* * MODULE NAME: rotate.c * * FUNCTION: * This module contains three different routines that compute rotation * matricies and load them into GL. * Detailed description is provided below. * * DEPENDENCIES: * The routines call GL matrix routines. * * HISTORY: * Developed & written, Linas Vepstas, Septmeber 1991 * Double precision port, March 1993 * * DETAILED DESCRIPTION: * This module contains three routines: * -------------------------------------------------------------------- * * void urot_about_axis (float m[4][4], --- returned * float angle, --- input * float axis[3]) --- input * Computes a rotation matrix. * The rotation is around the the direction specified by the argument * argument axis[3]. User may specify vector which is not of unit * length. The angle of rotation is specified in degrees, and is in the * right-handed direction. * * void rot_about_axis (float angle, --- input * float axis[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- * * void urot_axis (float m[4][4], --- returned * float omega, --- input * float axis[3]) --- input * Same as urot_about_axis(), but angle specified in radians. * It is assumed that the argument axis[3] is a vector of unit length. * If it is not of unit length, the returned matrix will not be correct. * * void rot_axis (float omega, --- input * float axis[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- * * void urot_omega (float m[4][4], --- returned * float omega[3]) --- input * same as urot_axis(), but the angle is taken as the length of the * vector omega[3] * * void rot_omega (float omega[3]) --- input * Same as above routine, except that the matrix is multiplied into the * GL matrix stack. * * -------------------------------------------------------------------- */ #include "gle.h" #include "port.h" /* ========================================================== */ void rot_axis (gleDouble omega, /* input */ gleDouble axis[3]) /* input */ { gleDouble m[4][4]; urot_axis (m, omega, axis); MULTMATRIX (m); } /* ========================================================== */ void rot_about_axis (gleDouble angle, /* input */ gleDouble axis[3]) /* input */ { gleDouble m[4][4]; urot_about_axis (m, angle, axis); MULTMATRIX (m); } /* ========================================================== */ void rot_omega (gleDouble axis[3]) /* input */ { gleDouble m[4][4]; urot_omega (m, axis); MULTMATRIX(m); } /* ========================================================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/copy.h0000644000175000017500000000064510061374075017722 0ustar debiandebian /* * * Written By Linas Vepstas November 1991 */ #define COPY_THREE_WORDS(A,B) { \ struct three_words { long a, b, c, }; \ *(struct three_words *) (A) = *(struct three_words *) (B); \ } #define COPY_FOUR_WORDS(A,B) { \ struct four_words { long a, b, c, d, }; \ *(struct four_words *) (A) = *(struct four_words *) (B); \ } /* ============================================================= */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/rot.h0000644000175000017500000000372710061374075017560 0ustar debiandebian /* * rot.h * * FUNCTION: * rotation matrix utilities * * HISTORY: * Linas Vepstas Aug 1990 */ /* ========================================================== */ /* * The MACROS below generate and return more traditional rotation * matrices -- matrices for rotations about principal axes. */ /* ========================================================== */ #define ROTX_CS(m,cosine,sine) \ { \ /* rotation about the x-axis */ \ \ m[0][0] = 1.0; \ m[0][1] = 0.0; \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = (cosine); \ m[1][2] = (sine); \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = -(sine); \ m[2][2] = (cosine); \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ } /* ========================================================== */ #define ROTY_CS(m,cosine,sine) \ { \ /* rotation about the y-axis */ \ \ m[0][0] = (cosine); \ m[0][1] = 0.0; \ m[0][2] = -(sine); \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = 1.0; \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = (sine); \ m[2][1] = 0.0; \ m[2][2] = (cosine); \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ } /* ========================================================== */ #define ROTZ_CS(m,cosine,sine) \ { \ /* rotation about the z-axis */ \ \ m[0][0] = (cosine); \ m[0][1] = (sine); \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = -(sine); \ m[1][1] = (cosine); \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = 0.0; \ m[2][2] = 1.0; \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ } /* ========================================================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/tube_gc.h0000644000175000017500000000650010061374075020354 0ustar debiandebian /* * FILE: * tube_gc.h * * FUNCTION: * This file defines all of the extrusion library state info * (i.e. the GLE graphics context). The GLE library is 'almost' * thread-safe, in that there really is only one global to worry * about. It should be a straight-forward change to move this * single global pointer into a per-thread storage (i.e. so * its fetched with pthread_getspecific()). If you develop * patches to enable this, please send them in to me -- * * HISTORY: * Linas Vepstas --- February 1993 * Added auto texture coord generation hooks, Linas April 1994 * * Copyright (C) 1993,1994 Linas Vepstas */ #ifndef GLE_TUBE_GC_H_ #define GLE_TUBE_GC_H_ typedef double gleTwoVec[2]; typedef struct { /* public methods */ void (*bgn_gen_texture) (int, double); void (*n3f_gen_texture) (float *); void (*n3d_gen_texture) (double *); void (*v3f_gen_texture) (float *, int, int); void (*v3d_gen_texture) (double *, int, int); void (*end_gen_texture) (void); /* protected members -- "general knowledge" stuff */ /* The joinstyle is set by the JoinStyle subroutine, * and controls the rendering of the tubing joins. */ int join_style; /* The 'slices' parameter controls the number of 'pie slices' * used to generate cones and cylinders. */ int slices; gleTwoVec *circle; /* 2D contour for circle */ gleTwoVec *norm; /* normal vectors for circle */ /* arguments passed into extrusion code */ int ncp; /* number of contour points */ gleTwoVec *contour; /* 2D contour */ gleTwoVec *cont_normal; /* 2D contour normals */ gleDouble *up; /* up vector */ int npoints; /* number of points in polyline */ gleVector *point_array; /* path */ gleColor *color_array; /* path colors */ gleAffine *xform_array; /* contour xforms */ /* private members, used by texturing code */ int num_vert; int segment_number; double segment_length; double accum_seg_len; double prev_x; double prev_y; void (*save_bgn_gen_texture) (int, double); void (*save_n3f_gen_texture) (float *); void (*save_n3d_gen_texture) (double *); void (*save_v3f_gen_texture) (float *, int, int); void (*save_v3d_gen_texture) (double *, int, int); void (*save_end_gen_texture) (void); } gleGC; extern gleGC *_gle_gc; extern gleGC * gleCreateGC (void); #define INIT_GC() {if (!_gle_gc) { _gle_gc = gleCreateGC(); atexit (gleDestroyGC);} } #define extrusion_join_style (_gle_gc->join_style) #define __TESS_SLICES (_gle_gc->slices) #define __TESS_CIRCLE (_gle_gc->circle) #define __TESS_NORM (_gle_gc->norm) #define __TUBE_CLOSE_CONTOUR (extrusion_join_style & TUBE_CONTOUR_CLOSED) #define __TUBE_DRAW_CAP (extrusion_join_style & TUBE_JN_CAP) #define __TUBE_DRAW_FACET_NORMALS (extrusion_join_style & TUBE_NORM_FACET) #define __TUBE_DRAW_PATH_EDGE_NORMALS (extrusion_join_style & TUBE_NORM_PATH_EDGE) #define __TUBE_STYLE (extrusion_join_style & TUBE_JN_MASK) #define __TUBE_RAW_JOIN (extrusion_join_style & TUBE_JN_RAW) #define __TUBE_CUT_JOIN (extrusion_join_style & TUBE_JN_CUT) #define __TUBE_ANGLE_JOIN (extrusion_join_style & TUBE_JN_ANGLE) #define __TUBE_ROUND_JOIN (extrusion_join_style & TUBE_JN_ROUND) #endif /* GLE_TUBE_GC_H_ */ /* ======================= END OF FILE ========================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/texgen.c0000644000175000017500000003151310061374075020233 0ustar debiandebian /* * texgen.c * * FUNCTION: * Implement a 'graphics context' for the GLE subsystem. * For the most part, this is for a big texture mapping hack. * * HISTORY: * Created by Linas Vepstas April 1994 * general cleanup December 1995 * * Copyright (c) 1994,1995 Linas Vepstas */ #include #include #include #include "gle.h" #include "port.h" #include "tube_gc.h" /* ======================================================= */ /* should really make this an adaptive algorithm ... */ #define _POLYCYL_TESS 20 static void setup_circle (gleGC *gc, int nslices); gleGC *_gle_gc = 0x0; gleGC * gleCreateGC (void) { gleGC * retval = (gleGC *) malloc (sizeof (gleGC)); retval -> bgn_gen_texture = 0x0; retval -> n3f_gen_texture = 0x0; retval -> n3d_gen_texture = 0x0; retval -> v3f_gen_texture = 0x0; retval -> v3d_gen_texture = 0x0; retval -> end_gen_texture = 0x0; retval -> save_bgn_gen_texture = 0x0; retval -> save_n3f_gen_texture = 0x0; retval -> save_n3d_gen_texture = 0x0; retval -> save_v3f_gen_texture = 0x0; retval -> save_v3d_gen_texture = 0x0; retval -> save_end_gen_texture = 0x0; retval -> join_style = TUBE_JN_ANGLE | TUBE_JN_CAP | TUBE_NORM_FACET; retval -> slices = 0; retval -> circle = 0x0; retval -> norm = 0x0; setup_circle (retval, _POLYCYL_TESS); retval -> ncp = 0; retval -> npoints = 0; retval -> num_vert = 0; retval -> segment_number = 0; retval -> segment_length = 0.0; retval -> accum_seg_len = 0.0; retval -> prev_x = 0.0; retval -> prev_y = 0.0; return retval; } void gleDestroyGC (void) { if (_gle_gc) { if (_gle_gc->circle) free (_gle_gc->circle); _gle_gc->circle = 0x0; free (_gle_gc); } _gle_gc = 0x0; } /* ======================================================= */ /* setup_circle is used to avoid excessive mallocs and frees * when drawing polycylinders and polycones */ static void setup_circle (gleGC *gc, int nslices) { int i; double c, s; if (!gc) return; if (0 > nslices) return; if (nslices == gc->slices) return; if (nslices > gc->slices) { gc->circle = (gleTwoVec *) realloc (gc->circle, sizeof(gleTwoVec)*2*nslices); gc->norm = &(gc->circle)[nslices]; } s = sin (2.0*M_PI/ ((double) nslices)); c = cos (2.0*M_PI/ ((double) nslices)); gc->norm [0][0] = 1.0; gc->norm [0][1] = 0.0; /* compute a perfect unit circle, using recursion relations */ for (i=1; inorm [i][0] = gc->norm[i-1][0] * c - gc->norm[i-1][1] * s; gc->norm [i][1] = gc->norm[i-1][0] * s + gc->norm[i-1][1] * c; } gc->slices = nslices; } int gleGetNumSides(void) { INIT_GC(); return (_gle_gc->slices); } void gleSetNumSides(int nslices) { INIT_GC(); setup_circle (_gle_gc, nslices); } /* ======================================================= */ #define segment_number (_gle_gc -> segment_number) #define segment_length (_gle_gc -> segment_length) #define accum_seg_len (_gle_gc -> accum_seg_len) #define num_vert (_gle_gc -> num_vert) #define prev_x (_gle_gc -> prev_x) #define prev_y (_gle_gc -> prev_y) /* ======================================================= */ static double save_nx = 0.0; static double save_ny = 0.0; static double save_nz = 0.0; static void save_normal (double *v) { save_nx = v[0]; save_ny = v[1]; save_nz = v[2]; } /* ======================================================= */ static void bgn_sphere_texgen (int inext, double len) { segment_number = inext - 1; segment_length = len; num_vert = 0; } /* ======================================================= */ /* * this routine assumes that the vertex passed in has been normalized * (i.e. is of unit length) */ static void sphere_texgen (double x, double y, double z, int jcnt, int which_end) { double theta, phi; /* let phi and theta range fro 0 to 1 */ phi = 0.5 * atan2 (x, y) / M_PI; phi += 0.5; theta = 1.0 - acos (z) / M_PI; /* if first vertex, merely record the texture coords */ if (num_vert == 0) { prev_x = phi; prev_y = theta; num_vert ++; } else { /* if texture coordinates changed radically, wrap them */ if ((prev_y - theta) > 0.6) { theta +=1.0; } else if ((prev_y - theta) < -0.6) { theta -=1.0; } /* else no-op */ prev_y = theta; /* if texture coordinates changed radically, wrap them */ if ((prev_x - phi) > 0.6) { phi +=1.0; } else if ((prev_x - phi) < -0.6) { phi -=1.0; } /* else no-op */ prev_x = phi; } T2F_D (phi, theta); } /* ======================================================= */ /* mappers */ static void vertex_sphere_texgen_v (double *v, int jcnt, int which_end) { double x = v[0]; double y = v[1]; double z = v[2]; double r; r = 1.0 / sqrt (x*x + y*y + z*z); x *= r; y *= r; z *= r; sphere_texgen (x, y, z, jcnt, which_end); } static void normal_sphere_texgen_v (double *v, int jcnt, int which_end) { sphere_texgen (save_nx, save_ny, save_nz, jcnt, which_end); } static void vertex_sphere_model_v (double *v, int jcnt, int which_end) { double x = _gle_gc->contour[jcnt][0]; double y = _gle_gc->contour[jcnt][1]; double z = v[2]; double r; r = 1.0 / sqrt (x*x + y*y + z*z); x *= r; y *= r; z *= r; sphere_texgen (x, y, z, jcnt, which_end); } static void normal_sphere_model_v (double *v, int jcnt, int which_end) { if (!(_gle_gc -> cont_normal)) return; sphere_texgen (_gle_gc->cont_normal[jcnt][0], _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); } /* ======================================================= */ static void bgn_z_texgen (int inext, double len) { /* accumulate the previous length */ accum_seg_len += segment_length; /* save current values */ segment_number = inext - 1; segment_length = len; /* reset counter on first segment */ if (1 >= segment_number) accum_seg_len = 0.0; num_vert = 0; } /* ======================================================= */ static void cylinder_texgen (double x, double y, double z, int jcnt, int which_end) { double phi; /* let phi and theta range fro 0 to 1 */ phi = 0.5 * atan2 (x, y) / M_PI; phi += 0.5; /* if first vertex, merely record the texture coords */ if (num_vert == 0) { prev_x = phi; num_vert ++; } else { /* if texture coordinates changed radically, wrap them */ if ((prev_x - phi) > 0.6) { phi +=1.0; } else if ((prev_x - phi) < -0.6) { phi -=1.0; } /* else no-op */ prev_x = phi; } if (FRONT == which_end) { T2F_D (phi, accum_seg_len); } if (BACK == which_end) { T2F_D (phi, accum_seg_len + segment_length); } } /* ======================================================= */ /* mappers */ static void vertex_cylinder_texgen_v (double *v, int jcnt, int which_end) { double x = v[0]; double y = v[1]; double z = v[2]; double r; r = 1.0 / sqrt (x*x + y*y); x *= r; y *= r; cylinder_texgen (x, y, z, jcnt, which_end); } static void normal_cylinder_texgen_v (double *v, int jcnt, int which_end) { cylinder_texgen (save_nx, save_ny, save_nz, jcnt, which_end); } static void vertex_cylinder_model_v (double *v, int jcnt, int which_end) { double x = _gle_gc->contour[jcnt][0]; double y = _gle_gc->contour[jcnt][1]; double z = v[2]; double r; r = 1.0 / sqrt (x*x + y*y); x *= r; y *= r; cylinder_texgen (x, y, z, jcnt, which_end); } static void normal_cylinder_model_v (double *v, int jcnt, int which_end) { if (!(_gle_gc -> cont_normal)) return; cylinder_texgen (_gle_gc->cont_normal[jcnt][0], _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); } /* ======================================================= */ static void flat_texgen (double x, double y, double z, int jcnt, int which_end) { if (FRONT == which_end) { T2F_D (x, accum_seg_len); } if (BACK == which_end) { T2F_D (x, accum_seg_len + segment_length); } } /* ======================================================= */ static void vertex_flat_texgen_v (double *v, int jcnt, int which_end) { flat_texgen (v[0], v[1], v[2], jcnt, which_end); } static void normal_flat_texgen_v (double *v, int jcnt, int which_end) { flat_texgen (save_nx, save_ny, save_nz, jcnt, which_end); } static void vertex_flat_model_v (double *v, int jcnt, int which_end) { flat_texgen (_gle_gc->contour[jcnt][0], _gle_gc->contour[jcnt][1], v[2], jcnt, which_end); } static void normal_flat_model_v (double *v, int jcnt, int which_end) { if (!(_gle_gc -> cont_normal)) return; flat_texgen (_gle_gc->cont_normal[jcnt][0], _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); } /* ======================================================= */ void gleTextureMode (int mode) { INIT_GC(); /* enable textureing by restoring the mode */ _gle_gc -> bgn_gen_texture = _gle_gc -> save_bgn_gen_texture; _gle_gc -> n3f_gen_texture = _gle_gc -> save_n3f_gen_texture; _gle_gc -> n3d_gen_texture = _gle_gc -> save_n3d_gen_texture; _gle_gc -> v3f_gen_texture = _gle_gc -> save_v3f_gen_texture; _gle_gc -> v3d_gen_texture = _gle_gc -> save_v3d_gen_texture; _gle_gc -> end_gen_texture = _gle_gc -> save_end_gen_texture; switch (mode&GLE_TEXTURE_STYLE_MASK) { case GLE_TEXTURE_VERTEX_FLAT: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = vertex_flat_texgen_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_FLAT: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = normal_flat_texgen_v; _gle_gc -> n3d_gen_texture = save_normal; break; case GLE_TEXTURE_VERTEX_MODEL_FLAT: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = vertex_flat_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_MODEL_FLAT: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = normal_flat_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_VERTEX_CYL: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = vertex_cylinder_texgen_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_CYL: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = normal_cylinder_texgen_v; _gle_gc -> n3d_gen_texture = save_normal; break; case GLE_TEXTURE_VERTEX_MODEL_CYL: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = vertex_cylinder_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_MODEL_CYL: _gle_gc -> bgn_gen_texture = bgn_z_texgen; _gle_gc -> v3d_gen_texture = normal_cylinder_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_VERTEX_SPH: _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; _gle_gc -> v3d_gen_texture = vertex_sphere_texgen_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_SPH: _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; _gle_gc -> v3d_gen_texture = normal_sphere_texgen_v; _gle_gc -> n3d_gen_texture = save_normal; break; case GLE_TEXTURE_VERTEX_MODEL_SPH: _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; _gle_gc -> v3d_gen_texture = vertex_sphere_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; case GLE_TEXTURE_NORMAL_MODEL_SPH: _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; _gle_gc -> v3d_gen_texture = normal_sphere_model_v; _gle_gc -> n3d_gen_texture = 0x0; break; default: break; } /* disable texturing, and save the mode */ if (!(mode & GLE_TEXTURE_ENABLE)) { _gle_gc -> save_bgn_gen_texture = _gle_gc -> bgn_gen_texture; _gle_gc -> save_n3f_gen_texture = _gle_gc -> n3f_gen_texture; _gle_gc -> save_n3d_gen_texture = _gle_gc -> n3d_gen_texture; _gle_gc -> save_v3f_gen_texture = _gle_gc -> v3f_gen_texture; _gle_gc -> save_v3d_gen_texture = _gle_gc -> v3d_gen_texture; _gle_gc -> save_end_gen_texture = _gle_gc -> end_gen_texture; _gle_gc -> bgn_gen_texture = 0x0; _gle_gc -> n3f_gen_texture = 0x0; _gle_gc -> n3d_gen_texture = 0x0; _gle_gc -> v3f_gen_texture = 0x0; _gle_gc -> v3d_gen_texture = 0x0; _gle_gc -> end_gen_texture = 0x0; } } /* ================== END OF FILE ========================= */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/extrude.c0000644000175000017500000006127610061374075020432 0ustar debiandebian /* * MODULE: extrude.c * * FUNCTION: * Provides code for the cylinder, cone and extrusion routines. * The cylinders/cones/etc. are built on top of general purpose * extrusions. The code that handles the general purpose extrusions * is in other modules. * * AUTHOR: * written by Linas Vepstas August/September 1991 * added polycone, February 1993 * * Copyright (C) 1991,1993,2003 Linas Vepstas */ #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" /* ============================================================ */ #ifndef COLOR_SIGNATURE /* The routine below determines the type of join style that will be * used for tubing. */ void gleSetJoinStyle (int style) { INIT_GC(); extrusion_join_style = style; } int gleGetJoinStyle (void) { INIT_GC(); return (extrusion_join_style); } #endif /* COLOR_SIGNATURE */ /* ============================================================ */ /* * draw a general purpose extrusion */ void gleSuperExtrusion (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]) /* 2D contour xforms */ { INIT_GC(); _gle_gc -> ncp = ncp; _gle_gc -> contour = contour; _gle_gc -> cont_normal = cont_normal; _gle_gc -> up = up; _gle_gc -> npoints = npoints; _gle_gc -> point_array = point_array; _gle_gc -> color_array = color_array; _gle_gc -> xform_array = xform_array; switch (__TUBE_STYLE) { case TUBE_JN_RAW: (void) extrusion_raw_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; case TUBE_JN_ANGLE: (void) extrusion_angle_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; case TUBE_JN_CUT: case TUBE_JN_ROUND: /* This routine used for both cut and round styles */ (void) extrusion_round_or_cut_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; default: break; } } /* ============================================================ */ void gleExtrusion (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[]) /* color of polyline */ { gleSuperExtrusion (ncp, contour, cont_normal, up, npoints, point_array, color_array, NULL); } /* ============================================================ */ /* should really make this an adaptive algorithm ... */ static void gen_polycone (int npoints, gleDouble point_array[][3], gleColor color_array[], gleDouble radius, gleDouble xform_array[][2][3]) { int saved_style; gleTwoVec *circle, *norm; int i, nslices; double v21[3]; double len; gleDouble up[3]; INIT_GC(); nslices = __TESS_SLICES; circle = __TESS_CIRCLE; norm = __TESS_NORM; /* this if statement forces this routine into double-duty for * both the polycone and the polycylinder routines */ if (xform_array != NULL) radius = 1.0; /* draw a norm using recursion relations */ for (i=0; iinf) (1+x/N) ** N * and take N=32. */ /* initialize translation and delta translation */ deltaTrans[0] = delta * dXformdTheta[0][2]; deltaTrans[1] = delta * dXformdTheta[1][2]; trans[0] = startXform[0][2]; trans[1] = startXform[1][2]; /* prepare the tangent matrix */ delta /= 32.0; mA[0][0] = 1.0 + delta * dXformdTheta[0][0]; mA[0][1] = delta * dXformdTheta[0][1]; mA[1][0] = delta * dXformdTheta[1][0]; mA[1][1] = 1.0 + delta * dXformdTheta[1][1]; /* compute exponential of matrix */ MATRIX_PRODUCT_2X2 (mB, mA, mA); /* squared */ MATRIX_PRODUCT_2X2 (mA, mB, mB); /* 4th power */ MATRIX_PRODUCT_2X2 (mB, mA, mA); /* 8th power */ MATRIX_PRODUCT_2X2 (mA, mB, mB); /* 16th power */ MATRIX_PRODUCT_2X2 (mB, mA, mA); /* 32nd power */ /* initialize running matrix */ COPY_MATRIX_2X2 (run, startXform); /* remember, the first point is hidden -- load some, any * xform for the first point */ xforms[0][0][0] = startXform[0][0]; xforms[0][0][1] = startXform[0][1]; xforms[0][0][2] = startXform[0][2]; xforms[0][1][0] = startXform[1][0]; xforms[0][1][1] = startXform[1][1]; xforms[0][1][2] = startXform[1][2]; for (i=1; i #include "port.h" #include "vvector.h" #define BACKWARDS_INTERSECT (2) /* ========================================================== */ /* * the Degenerate_Tolerance token represents the greatest amount by * which different scales in a graphics environment can differ before * they should be considered "degenerate". That is, when one vector is * a million times longer than another, changces are that the second will * be less than a pixel long, and therefore was probably meant to be * degenerate (by the CAD package, etc.) But what should this tolerance * be? At least 1 in one thousand (since screen sizes are 1K pixels), but * less than 1 in 4 million (since this is the limit of single-precision * floating point accuracy). Of course, if double precision were used, * then the tolerance could be increased. * * Potentially, this naive assumption could cause problems if the CAD * package attempts to zoom in on small details, and turns out, certain * points should not have been degenerate. The problem presented here * is that the tolerance could run out before single-precision ran * out, and so the CAD packages would perceive this as a "bug". * One alternative is to fiddle around & try to tighten the tolerance. * However, the right alternative is to code the graphics pipeline in * double-precision (and tighten the tolerance). * * By the way, note that Degernate Tolerance is a "dimensionless" * quantitiy -- it has no units -- it does not measure feet, inches, * millimeters or pixels. It is used only in the computations of ratios * and relative lengths. */ /* * Right now, the tolerance is set to 2 parts in a million, which * corresponds to a 19-bit distinction of mantissas. Note that * single-precsion numbers have 24 bit mantissas. */ #define DEGENERATE_TOLERANCE (0.000002) /* ========================================================== */ /* * The macro and subroutine INTERSECT are designed to compute the * intersection of a line (defined by the points v1 and v2) and a plane * (defined as plane which is normal to the vector n, and contains the * point p). Both return the point sect, which is the point of * interesection. * * This MACRO attemps to be fairly robust by checking for a divide by * zero. */ /* ========================================================== */ /* * HACK ALERT * The intersection parameter t has the nice property that if t>1, * then the intersection is "in front of" p1, and if t<0, then the * intersection is "behind" p2. Unfortunately, as the intersecting plane * and the line become parallel, t wraps through infinity -- i.e. t can * become so large that t becomes "greater than infinity" and comes back * as a negative number (i.e. winding number hopped by one unit). We * have no way of detecting this situation without adding gazzillions * of lines of code of topological algebra to detect the winding number; * and this would be incredibly difficult, and ruin performance. * * Thus, we've installed a cheap hack for use by the "cut style" drawing * routines. If t proves to be a large negative number (more negative * than -5), then we assume that t was positive and wound through * infinity. This makes most cuts look good, without introducing bogus * cuts at infinity. */ /* ========================================================== */ #define INTERSECT(valid,sect,p,n,v1,v2) \ { \ gleDouble deno, numer, t, omt; \ \ deno = (v1[0] - v2[0]) * n[0]; \ deno += (v1[1] - v2[1]) * n[1]; \ deno += (v1[2] - v2[2]) * n[2]; \ \ if (deno == 0.0) { \ valid = FALSE; \ VEC_COPY (n, v1); \ /* printf ("Intersect: Warning: line is coplanar with plane \n"); */ \ } else { \ \ valid = TRUE; \ numer = (p[0] - v2[0]) * n[0]; \ numer += (p[1] - v2[1]) * n[1]; \ numer += (p[2] - v2[2]) * n[2]; \ \ t = numer / deno; \ omt = 1.0 - t; \ \ /* if (t < -5.0) valid = 2; HACK ALERT See above */ \ \ /* if t is HUGE, then plane and line are almost co-planar */ \ if ((1.0 < t * DEGENERATE_TOLERANCE) || \ (-1.0 > t * DEGENERATE_TOLERANCE)) valid = FALSE; \ \ sect[0] = t * v1[0] + omt * v2[0]; \ sect[1] = t * v1[1] + omt * v2[1]; \ sect[2] = t * v1[2] + omt * v2[2]; \ } \ } /* ========================================================== */ /* * The macro and subroutine BISECTING_PLANE compute a normal vector that * describes the bisecting plane between three points (v1, v2 and v3). * This bisecting plane has the following properties: * 1) it contains the point v2 * 2) the angle it makes with v21 == v2 - v1 is equal to the angle it * makes with v32 == v3 - v2 * 3) it is perpendicular to the plane defined by v1, v2, v3. * * Having input v1, v2, and v3, it returns a unit vector n. * * In some cases, the user may specify degenerate points, and still * expect "reasonable" or "obvious" behaviour. The "expected" * behaviour for these degenerate cases is: * * 1) if v1 == v2 == v3, then return n=0 * 2) if v1 == v2, then return v32 (normalized). * 3) if v2 == v3, then return v21 (normalized). * 4) if v1, v2 and v3 co-linear, then return v21 (normalized). * * Mathematically, these special cases "make sense" -- we just have to * code around potential divide-by-zero's in the code below. */ /* ========================================================== */ #define BISECTING_PLANE(valid,n,v1,v2,v3) \ { \ double v21[3], v32[3]; \ double len21, len32; \ double dot; \ \ VEC_DIFF (v21, v2, v1); \ VEC_DIFF (v32, v3, v2); \ \ VEC_LENGTH (len21, v21); \ VEC_LENGTH (len32, v32); \ \ if (len21 <= DEGENERATE_TOLERANCE * len32) { \ \ if (len32 == 0.0) { \ /* all three points lie ontop of one-another */ \ VEC_ZERO (n); \ valid = FALSE; \ } else { \ /* return a normalized copy of v32 as bisector */ \ len32 = 1.0 / len32; \ VEC_SCALE (n, len32, v32); \ valid = TRUE; \ } \ \ } else { \ \ valid = TRUE; \ \ if (len32 <= DEGENERATE_TOLERANCE * len21) { \ /* return a normalized copy of v21 as bisector */ \ len21 = 1.0 / len21; \ VEC_SCALE (n, len21, v21); \ \ } else { \ \ /* normalize v21 to be of unit length */ \ len21 = 1.0 / len21; \ VEC_SCALE (v21, len21, v21); \ \ /* normalize v32 to be of unit length */ \ len32 = 1.0 / len32; \ VEC_SCALE (v32, len32, v32); \ \ VEC_DOT_PRODUCT (dot, v32, v21); \ \ /* if dot == 1 or -1, then points are colinear */ \ if ((dot >= (1.0-DEGENERATE_TOLERANCE)) || \ (dot <= (-1.0+DEGENERATE_TOLERANCE))) { \ VEC_COPY (n, v21); \ } else { \ \ /* go do the full computation */ \ n[0] = dot * (v32[0] + v21[0]) - v32[0] - v21[0]; \ n[1] = dot * (v32[1] + v21[1]) - v32[1] - v21[1]; \ n[2] = dot * (v32[2] + v21[2]) - v32[2] - v21[2]; \ \ /* if above if-test's passed, \ * n should NEVER be of zero length */ \ VEC_NORMALIZE (n); \ } \ } \ } \ } /* prototype for those who don't use the #define directly */ int bisecting_plane (gleDouble n[3], /* returned */ gleDouble v1[3], /* input */ gleDouble v2[3], /* input */ gleDouble v3[3]); /* input */ /* ========================================================== */ /* * The block of code below is ifdef'd out, and is here for reference * purposes only. It performs the "mathematically right thing" for * computing a bisecting plane, but is, unfortunately, subject ot noise * in the presence of near degenerate points. Since computer graphics, * due to sloppy coding, laziness, or correctness, is filled with * degenerate points, we can't really use this version. The code above * is far more appropriate for graphics. */ #ifdef MATHEMATICALLY_EXACT_GRAPHICALLY_A_KILLER #define BISECTING_PLANE(n,v1,v2,v3) \ { \ double v21[3], v32[3]; \ double len21, len32; \ double dot; \ \ VEC_DIFF (v21, v2, v1); \ VEC_DIFF (v32, v3, v2); \ \ VEC_LENGTH (len21, v21); \ VEC_LENGTH (len32, v32); \ \ if (len21 == 0.0) { \ \ if (len32 == 0.0) { \ /* all three points lie ontop of one-another */ \ VEC_ZERO (n); \ valid = FALSE; \ } else { \ /* return a normalized copy of v32 as bisector */ \ len32 = 1.0 / len32; \ VEC_SCALE (n, len32, v32); \ } \ \ } else { \ \ /* normalize v21 to be of unit length */ \ len21 = 1.0 / len21; \ VEC_SCALE (v21, len21, v21); \ \ if (len32 == 0.0) { \ /* return a normalized copy of v21 as bisector */ \ VEC_COPY (n, v21); \ } else { \ \ /* normalize v32 to be of unit length */ \ len32 = 1.0 / len32; \ VEC_SCALE (v32, len32, v32); \ \ VEC_DOT_PRODUCT (dot, v32, v21); \ \ /* if dot == 1 or -1, then points are colinear */ \ if ((dot == 1.0) || (dot == -1.0)) { \ VEC_COPY (n, v21); \ } else { \ \ /* go do the full computation */ \ n[0] = dot * (v32[0] + v21[0]) - v32[0] - v21[0]; \ n[1] = dot * (v32[1] + v21[1]) - v32[1] - v21[1]; \ n[2] = dot * (v32[2] + v21[2]) - v32[2] - v21[2]; \ \ /* if above if-test's passed, \ * n should NEVER be of zero length */ \ VEC_NORMALIZE (n); \ } \ } \ } \ } #endif /* ========================================================== */ /* * This macro computes the plane perpendicular to the the plane * defined by three points, and whose normal vector is givven as the * difference between the two vectors ... * * (See way below for the "math" model if you want to understand this. * The comments about relative errors above apply here.) */ #define CUTTING_PLANE(valid,n,v1,v2,v3) \ { \ double v21[3], v32[3]; \ double len21, len32; \ double lendiff; \ \ VEC_DIFF (v21, v2, v1); \ VEC_DIFF (v32, v3, v2); \ \ VEC_LENGTH (len21, v21); \ VEC_LENGTH (len32, v32); \ \ if (len21 <= DEGENERATE_TOLERANCE * len32) { \ \ if (len32 == 0.0) { \ /* all three points lie ontop of one-another */ \ VEC_ZERO (n); \ valid = FALSE; \ } else { \ /* return a normalized copy of v32 as cut-vector */ \ len32 = 1.0 / len32; \ VEC_SCALE (n, len32, v32); \ valid = TRUE; \ } \ \ } else { \ \ valid = TRUE; \ \ if (len32 <= DEGENERATE_TOLERANCE * len21) { \ /* return a normalized copy of v21 as cut vector */ \ len21 = 1.0 / len21; \ VEC_SCALE (n, len21, v21); \ } else { \ \ /* normalize v21 to be of unit length */ \ len21 = 1.0 / len21; \ VEC_SCALE (v21, len21, v21); \ \ /* normalize v32 to be of unit length */ \ len32 = 1.0 / len32; \ VEC_SCALE (v32, len32, v32); \ \ VEC_DIFF (n, v21, v32); \ VEC_LENGTH (lendiff, n); \ \ /* if the perp vector is very small, then the two \ * vectors are darn near collinear, and the cut \ * vector is probably poorly defined. */ \ if (lendiff < DEGENERATE_TOLERANCE) { \ VEC_ZERO (n); \ valid = FALSE; \ } else { \ lendiff = 1.0 / lendiff; \ VEC_SCALE (n, lendiff, n); \ } \ } \ } \ } /* ========================================================== */ #ifdef MATHEMATICALLY_EXACT_GRAPHICALLY_A_KILLER #define CUTTING_PLANE(n,v1,v2,v3) \ { \ double v21[3], v32[3]; \ \ VEC_DIFF (v21, v2, v1); \ VEC_DIFF (v32, v3, v2); \ \ VEC_NORMALIZE (v21); \ VEC_NORMALIZE (v32); \ \ VEC_DIFF (n, v21, v32); \ VEC_NORMALIZE (n); \ } #endif /* ========================================================== */ /* sets "colin" to true if the three points are colinear, * else false. Note that if any two points are degenerate, * then they are colinear. * We are careful to make sure that the comparison * is unit-less, i.e. that the lengths of the individual * segments is normalized. By re-arrangement, avoid overhead of * two square roots and two divides. */ #define COLINEAR(colin,v1,v2,v3) \ { \ double v21[3], v32[3]; \ double len21, len32, dot; \ \ VEC_DIFF (v21, v2, v1); \ VEC_DIFF (v32, v3, v2); \ \ VEC_DOT_PRODUCT (len21, v21, v21); \ VEC_DOT_PRODUCT (len32, v32, v32); \ colin = (len32 <= (DEGENERATE_TOLERANCE*len21)); \ colin = colin || (len21 <= (DEGENERATE_TOLERANCE*len32)); \ VEC_DOT_PRODUCT (dot, v21, v32); \ colin = colin || ((len21*len32-dot*dot) <= \ (len21*len32*DEGENERATE_TOLERANCE*DEGENERATE_TOLERANCE)); \ } /* ========================================================== */ /* sets "degen" to true if the two points are degenerate, * else false. We are careful to make sure that the comparison * is unit-less, i.e. that the lengths of the individual * segments is normalized. By re-arrangement, avoid overhead of * two square roots and two divides. */ #define DEGENERATE(degen,v1,v2) \ { \ double diff[3], summa[3]; \ double dlen, slen; \ \ VEC_DIFF (diff, v2, v1); \ VEC_DOT_PRODUCT (dlen, diff, diff); \ VEC_SUM (summa, v1, v2); \ VEC_DOT_PRODUCT (slen, summa, summa); \ degen = (dlen <= \ (DEGENERATE_TOLERANCE*DEGENERATE_TOLERANCE*slen)); \ } /* ============================================================ */ /* This macro is used in several places to cycle through a series of * points to find the next non-degenerate point in a series */ #define FIND_NON_DEGENERATE_POINT(inext,npoints,len,diff,point_array) \ { \ gleDouble slen; \ gleDouble summa[3]; \ \ do { \ /* get distance to next point */ \ VEC_DIFF (diff, point_array[inext+1], point_array[inext]); \ VEC_LENGTH (len, diff); \ VEC_SUM (summa, point_array[inext+1], point_array[inext]); \ VEC_LENGTH (slen, summa); \ slen *= DEGENERATE_TOLERANCE; \ inext ++; \ } while ((len <= slen) && (inext < npoints-1)); \ } /* ========================================================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/ex_cut_round.c0000644000175000017500000014302010061374075021434 0ustar debiandebian /* * MODULE NAME: ex_cut_round.c * * FUNCTION: * This module contains code that draws extrusions with cut or round * join styles. The cut join style is a beveled edge. * The code also inserts colors and normals if appropriate. * * HISTORY: * written by Linas Vepstas August/September 1991 * split into multiple compile units, Linas, October 1991 * added normal vectors Linas, October 1991 * Fixed filleting problem, Linas February 1993 * Modified to handle round joins as well (based on common code), * Linas, March 1993 * work around OpenGL's lack of support for concave polys, June 1994 * * Copyright (C) 1991,1993,1994,2003 Linas Vepstas */ #include #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" #include "segment.h" typedef void (*gleCapCallback) (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards); #define INVALID_BUG_NEEDS_FIXING 0 #ifdef NONCONCAVE_CAPS /* ============================================================ */ /* * This subroutine draws a flat cap, to close off the cut ends * of the cut-style join. Because OpenGL doe not natively handle * concave polygons, this will cause some artifacts to appear on the * screen. */ static void draw_cut_style_cap_callback (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards) { int i; if (face_color != NULL) C3F (face_color); if (frontwards) { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] < 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } BGNPOLYGON(); for (i=0; i 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } /* the sense of the loop is reversed for backfacing culling */ BGNPOLYGON(); for (i=iloop-1; i>-1; i--) { V3F_D (cap[i], i, BACK_CAP); } ENDPOLYGON(); } } #else /* NONCONCAVE_CAPS */ /* ============================================================ */ /* * This subroutine draws a flat cap, to close off the cut ends * of the cut-style join. Properly handles concave endcaps. */ static void draw_cut_style_cap_callback (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards) { #ifdef GL_32 int i; #endif /* GL_32 */ #ifdef DELICATE_TESSELATOR int i; int is_colinear; double *previous_vertex = 0x0; double *first_vertex = 0x0; #endif /* DELICATE_TESSELATOR */ #ifdef OPENGL_10 GLUtriangulatorObj *tobj; tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); #endif /* OPENGL_10 */ if (face_color != NULL) C3F (face_color); if (frontwards) { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] < 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } #ifdef GL_32 BGNPOLYGON(); for (i=0; i 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } /* the sense of the loop is reversed for backfacing culling */ #ifdef GL_32 BGNPOLYGON(); for (i=iloop-1; i>-1; i--) { V3F_D (cap[i], i, BACK_CAP); } ENDPOLYGON(); #endif /* GL_32 */ #ifdef OPENGL_10 #ifdef LENIENT_TESSELATOR gluBeginPolygon (tobj); for (i=iloop-1; i>-1; i--) { gluTessVertex (tobj, cap[i], cap[i]); } gluEndPolygon (tobj); #endif /* LENIENT_TESSELATOR */ #ifdef DELICATE_TESSELATOR gluBeginPolygon (tobj); first_vertex = 0x0; previous_vertex = cap[0]; for (i=iloop-1; i>0; i--) { COLINEAR (is_colinear, previous_vertex, cap[i], cap[i-1]); if (!is_colinear) { gluTessVertex (tobj, cap[i], cap[i]); previous_vertex = cap[i]; if (!first_vertex) first_vertex = previous_vertex; } } if (!first_vertex) first_vertex = cap[iloop-1]; COLINEAR (is_colinear, previous_vertex, cap[0], first_vertex); if (!is_colinear) gluTessVertex (tobj, cap[0], cap[0]); gluEndPolygon (tobj); #endif /* DELICATE_TESSELATOR */ #endif /* OPENGL_10 */ } #ifdef OPENGL_10 gluDeleteTess (tobj); #endif /* OPENGL_10 */ } #endif /* NONCONCAVE_ENDCAPS */ /* ============================================================ */ /* * This subroutine matchs the cap callback template, but is a no-op */ static void null_cap_callback (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards) {} /* ============================================================ */ /* * This little routine draws the little idd-biddy fillet triangle with * the right color, normal, etc. * * HACK ALERT -- there are two aspects to this routine/interface that * are "unfinished". * 1) the third point of the triangle should get a color thats * interpolated beween the front and back color. The interpolant * is not currently being computed. The error introduced by not * doing this should be tiny and/or non-exitant in almost all * expected uses of this code. * * 2) additional normal vectors should be supplied, and these should * be interpolated to fit. Currently, this is not being done. As * above, the expected error of not doing this should be tiny and/or * non-existant in almost all expected uses of this code. */ static void draw_fillet_triangle_plain (gleDouble va[3], gleDouble vb[3], gleDouble vc[3], int face, float front_color[3], float back_color[3]) { if (front_color != NULL) C3F (front_color); BGNTMESH (-5, 0.0); if (face) { V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); } else { V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); } V3F (vc, INVALID_BUG_NEEDS_FIXING, FILLET); ENDTMESH (); } /* ============================================================ */ /* * This little routine draws the little idd-biddy fillet triangle with * the right color, normal, etc. * * HACK ALERT -- there are two aspects to this routine/interface that * are "unfinished". * 1) the third point of the triangle should get a color thats * interpolated beween the front and back color. The interpolant * is not currently being computed. The error introduced by not * doing this should be tiny and/or non-exitant in almost all * expected uses of this code. * * 2) additional normal vectors should be supplied, and these should * be interpolated to fit. Currently, this is not being done. As * above, the expected error of not doing this should be tiny and/or * non-existant in almost all expected uses of this code. */ static void draw_fillet_triangle_n_norms (gleDouble va[3], gleDouble vb[3], gleDouble vc[3], int face, float front_color[3], float back_color[3], double na[3], double nb[3]) { if (front_color != NULL) C3F (front_color); BGNTMESH (-5, 0.0); if (__TUBE_DRAW_FACET_NORMALS) { N3F_D (na); if (face) { V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); } else { V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); } V3F (vc, INVALID_BUG_NEEDS_FIXING, FILLET); } else { if (face) { N3F_D (na); V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); N3F_D (nb); V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); } else { N3F_D (nb); V3F (vb, INVALID_BUG_NEEDS_FIXING, FILLET); N3F_D (na); V3F (va, INVALID_BUG_NEEDS_FIXING, FILLET); N3F_D (nb); } V3F (vc, INVALID_BUG_NEEDS_FIXING, FILLET); } ENDTMESH (); } /* ============================================================ */ static void draw_fillets_and_join_plain (int ncp, gleDouble trimmed_loop[][3], gleDouble untrimmed_loop[][3], int is_trimmed[], gleDouble bis_origin[3], gleDouble bis_vector[3], float front_color[3], float back_color[3], gleDouble cut_vector[3], int face, gleCapCallback cap_callback) { int istop; int icnt, icnt_prev, iloop; double *cap_loop; gleDouble sect[3]; gleDouble tmp_vec[3]; int save_style = 0; int was_trimmed = FALSE; cap_loop = (double *) malloc ((ncp+3)*3*sizeof (double)); /* * If the first point is trimmed, keep going until one * is found that is not trimmed, and start join there. */ save_style = gleGetJoinStyle (); icnt = 0; iloop = 0; if (!is_trimmed[0]) { /* if the first point on the contour isn't trimmed, go ahead and * drop an edge down to the bisecting plane, (thus starting the * join). (Only need to do this for cut join, its bad if done for * round join). (Also, do this only for open contours; leads to * bugs when done for closed contours). */ if ((__TUBE_CUT_JOIN) && (!(save_style & TUBE_CONTOUR_CLOSED))) { VEC_SUM (tmp_vec, trimmed_loop[0], bis_vector); INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[0], tmp_vec); VEC_COPY ( (&cap_loop[3*iloop]), sect); iloop ++; } VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[0])); iloop++; icnt_prev = icnt; icnt ++; } else { /* else, loop until an untrimmed point is found */ was_trimmed = TRUE; while (is_trimmed[icnt]) { icnt_prev = icnt; icnt ++; if (icnt >= ncp) { free (cap_loop); return; /* oops - everything was trimmed */ } } } /* Start walking around the end cap. Every time the end loop is * trimmed, we know we'll need to draw a fillet triangle. In * addition, after every pair of visibility changes, we draw a cap. */ if (__TUBE_CLOSE_CONTOUR) { istop = ncp; } else { istop = ncp-1; } /* save the join style, and disable a closed contour. * Need to do this so partial contours don't close up. */ gleSetJoinStyle (save_style & ~TUBE_CONTOUR_CLOSED); for (; icnt_prev < istop; icnt_prev ++, icnt ++, icnt %= ncp) { /* There are four interesting cases for drawing caps and fillets: * 1) this & previous point were trimmed. Don't do anything, * advance counter. * 2) this point trimmed, previous not -- draw fillet, and * draw cap. * 3) this point not trimmed, previous one was -- compute * intersection point, draw fillet with it, and save * point for cap contour. * 4) this & previous point not trimmed -- save for endcap. */ /* Case 1 -- noop, just advance pointers */ if (is_trimmed[icnt_prev] && is_trimmed[icnt]) { } /* Case 2 -- Hah! first point! compute intersect & draw fillet! */ if (is_trimmed[icnt_prev] && !is_trimmed[icnt]) { /* important note: the array "untrimmed" contains valid * untrimmed data ONLY when is_trim is TRUE. Otherwise, * only "trim" containes valid data */ /* compute intersection */ INNERSECT (sect, bis_origin, bis_vector, untrimmed_loop[icnt_prev], trimmed_loop[icnt]); /* Draw Fillet */ draw_fillet_triangle_plain (trimmed_loop[icnt_prev], trimmed_loop[icnt], sect, face, front_color, back_color); VEC_COPY ( (&cap_loop[3*iloop]), sect); iloop ++; VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); iloop++; } /* Case 3 -- add to collection of points */ if (!is_trimmed[icnt_prev] && !is_trimmed[icnt]) { VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); iloop++; } /* Case 4 -- Hah! last point! draw fillet & draw cap! */ if (!is_trimmed[icnt_prev] && is_trimmed[icnt]) { was_trimmed = TRUE; /* important note: the array "untrimmed" contains valid * untrimmed data ONLY when is_trim is TRUE. Otherwise, * only "trim" containes valid data */ /* compute intersection */ INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[icnt_prev], untrimmed_loop[icnt]); /* Draw Fillet */ draw_fillet_triangle_plain (trimmed_loop[icnt_prev], trimmed_loop[icnt], sect, face, front_color, back_color); VEC_COPY ( (&cap_loop[3*iloop]), sect); iloop ++; /* draw cap */ if (iloop >= 3) (*cap_callback) (iloop, (gleDouble (*)[3]) cap_loop, front_color, cut_vector, bis_vector, NULL, face); /* reset cap counter */ iloop = 0; } } /* now, finish up in the same way that we started. If the last * point of the contour is visible, drop an edge to the bisecting * plane, thus finishing the join, and then, draw the join! */ icnt --; /* decrement to make up for loop exit condititons */ icnt += ncp; icnt %= ncp; if ((!is_trimmed[icnt]) && (iloop >= 2)) { VEC_SUM (tmp_vec, trimmed_loop[icnt], bis_vector); INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[icnt], tmp_vec); VEC_COPY ( (&cap_loop[3*iloop]), sect); iloop ++; /* if nothing was ever trimmed, then we want to draw the * cap the way the user asked for it -- closed or not closed. * Therefore, reset the closure flag to its original state. */ if (!was_trimmed) { gleSetJoinStyle (save_style); } /* draw cap */ (*cap_callback) (iloop, (gleDouble (*)[3]) cap_loop, front_color, cut_vector, bis_vector, NULL, face); } /* rest to the saved style */ gleSetJoinStyle (save_style); free (cap_loop); } /* ============================================================ */ static void draw_fillets_and_join_n_norms (int ncp, gleDouble trimmed_loop[][3], gleDouble untrimmed_loop[][3], int is_trimmed[], gleDouble bis_origin[3], gleDouble bis_vector[3], double normals[][3], float front_color[3], float back_color[3], gleDouble cut_vector[3], int face, gleCapCallback cap_callback) { int istop; int icnt, icnt_prev, iloop; double *cap_loop, *norm_loop; gleDouble sect[3]; gleDouble tmp_vec[3]; int save_style = 0; int was_trimmed = FALSE; save_style = gleGetJoinStyle (); cap_loop = (double *) malloc ((ncp+3)*3*2*sizeof (double)); norm_loop = cap_loop + (ncp+3)*3; /* * If the first point is trimmed, keep going until one * is found that is not trimmed, and start join there. */ icnt = 0; iloop = 0; if (!is_trimmed[0]) { /* if the first point on the contour isn't trimmed, go ahead and * drop an edge down to the bisecting plane, (thus starting the * join). (Only need to do this for cut join, its bad if done for * round join). (Also, leads to bugs when done for closed * contours ... do this only if contour is open). */ if ((__TUBE_CUT_JOIN) && (!(save_style & TUBE_CONTOUR_CLOSED))) { VEC_SUM (tmp_vec, trimmed_loop[0], bis_vector); INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[0], tmp_vec); VEC_COPY ( (&cap_loop[3*iloop]), sect); VEC_COPY ( (&norm_loop[3*iloop]), normals[0]); iloop ++; } VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[0])); VEC_COPY ( (&norm_loop[3*iloop]), normals[0]); iloop++; icnt_prev = icnt; icnt ++; } else { /* else, loop until an untrimmed point is found */ was_trimmed = TRUE; while (is_trimmed[icnt]) { icnt_prev = icnt; icnt ++; if (icnt >= ncp) { free (cap_loop); return; /* oops - everything was trimmed */ } } } /* Start walking around the end cap. Every time the end loop is * trimmed, we know we'll need to draw a fillet triangle. In * addition, after every pair of visibility changes, we draw a cap. */ if (__TUBE_CLOSE_CONTOUR) { istop = ncp; } else { istop = ncp-1; } /* save the join style, and disable a closed contour. * Need to do this so partial contours don't close up. */ save_style = gleGetJoinStyle (); gleSetJoinStyle (save_style & ~TUBE_CONTOUR_CLOSED); for (; icnt_prev < istop; icnt_prev ++, icnt ++, icnt %= ncp) { /* There are four interesting cases for drawing caps and fillets: * 1) this & previous point were trimmed. Don't do anything, * advance counter. * 2) this point trimmed, previous not -- draw fillet, and * draw cap. * 3) this point not trimmed, previous one was -- compute * intersection point, draw fillet with it, and save * point for cap contour. * 4) this & previous point not trimmed -- save for endcap. */ /* Case 1 -- noop, just advance pointers */ if (is_trimmed[icnt_prev] && is_trimmed[icnt]) { } /* Case 2 -- Hah! first point! compute intersect & draw fillet! */ if (is_trimmed[icnt_prev] && !is_trimmed[icnt]) { /* important note: the array "untrimmed" contains valid * untrimmed data ONLY when is_trim is TRUE. Otherwise, * only "trim" containes valid data */ /* compute intersection */ INNERSECT (sect, bis_origin, bis_vector, untrimmed_loop[icnt_prev], trimmed_loop[icnt]); /* Draw Fillet */ draw_fillet_triangle_n_norms (trimmed_loop[icnt_prev], trimmed_loop[icnt], sect, face, front_color, back_color, normals[icnt_prev], normals[icnt]); VEC_COPY ( (&cap_loop[3*iloop]), sect); VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt_prev]); iloop ++; VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); iloop++; } /* Case 3 -- add to collection of points */ if (!is_trimmed[icnt_prev] && !is_trimmed[icnt]) { VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); iloop++; } /* Case 4 -- Hah! last point! draw fillet & draw cap! */ if (!is_trimmed[icnt_prev] && is_trimmed[icnt]) { was_trimmed = TRUE; /* important note: the array "untrimmed" contains valid * untrimmed data ONLY when is_trim is TRUE. Otherwise, * only "trim" containes valid data */ /* compute intersection */ INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[icnt_prev], untrimmed_loop[icnt]); /* Draw Fillet */ draw_fillet_triangle_n_norms (trimmed_loop[icnt_prev], trimmed_loop[icnt], sect, face, front_color, back_color, normals[icnt_prev], normals[icnt]); VEC_COPY ( (&cap_loop[3*iloop]), sect); /* OK, maybe phong normals are wrong, but at least facet * normals will come out OK. */ if (__TUBE_DRAW_FACET_NORMALS) { VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt_prev]); } else { VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); } iloop ++; /* draw cap */ if (iloop >= 3) (*cap_callback) (iloop, (gleVector *) cap_loop, front_color, cut_vector, bis_vector, (gleVector *) norm_loop, face); /* reset cap counter */ iloop = 0; } } /* now, finish up in the same way that we started. */ icnt --; /* decrement to make up for loop exit condititons */ icnt += ncp; icnt %= ncp; if ((!is_trimmed[icnt]) && (iloop >= 2)) { /* If the last point of the contour is visible, drop an edge * to the bisecting plane, thus finishing the join. * Note that doing this leads to bugs if done for closed * contours ... do this only if contour is open. */ if ((__TUBE_CUT_JOIN) && (!(save_style & TUBE_CONTOUR_CLOSED))) { VEC_SUM (tmp_vec, trimmed_loop[icnt], bis_vector); INNERSECT (sect, bis_origin, bis_vector, trimmed_loop[icnt], tmp_vec); VEC_COPY ( (&cap_loop[3*iloop]), sect); VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); iloop ++; } /* if nothing was ever trimmed, then we want to draw the * cap the way the user asked for it -- closed or not closed. * Therefore, reset the closure flag to its original state. */ if (!was_trimmed) { gleSetJoinStyle (save_style); } /* draw cap */ (*cap_callback) (iloop, (gleVector *) cap_loop, front_color, cut_vector, bis_vector, (gleVector *) norm_loop, face); } /* rest to the saved style */ gleSetJoinStyle (save_style); free (cap_loop); } /* ============================================================ */ /* This routine draws "cut" style extrusions. */ void extrusion_round_or_cut_join (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2],/* 2D normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]) /* 2D contour xforms */ { int i, j; int inext, inextnext; gleDouble m[4][4]; gleDouble tube_len, seg_len; gleDouble diff[3]; gleDouble bi_0[3], bi_1[3]; /* bisecting plane */ gleDouble bisector_0[3], bisector_1[3]; /* bisecting plane */ gleDouble cut_0[3], cut_1[3]; /* cutting planes */ gleDouble lcut_0[3], lcut_1[3]; /* cutting planes */ int valid_cut_0, valid_cut_1; /* flag -- cut vector is valid */ gleDouble end_point_0[3], end_point_1[3]; gleDouble torsion_point_0[3], torsion_point_1[3]; gleDouble isect_point[3]; gleDouble origin[3], neg_z[3]; gleDouble yup[3]; /* alternate up vector */ gleDouble *front_cap, *back_cap; /* arrays containing the end caps */ gleDouble *front_loop, *back_loop; /* arrays containing the tube ends */ double *front_norm, *back_norm; /* arrays containing normal vecs */ double *norm_loop=0x0, *tmp; /* normal vectors, cast into 3d from 2d */ int *front_is_trimmed, *back_is_trimmed; /* T or F */ float *front_color, *back_color; /* pointers to segment colors */ gleCapCallback cap_callback = 0x0 ; /* function callback to draw cap */ gleCapCallback tmp_cap_callback = 0x0; /* function callback to draw cap */ int join_style_is_cut; /* TRUE if join style is cut */ double dot; /* partial dot product */ char *mem_anchor; int first_time = TRUE; gleDouble *cut_vec; /* create a local, block scope copy of of the join style. * this will alleviate wasted cycles and register write-backs */ /* choose the right callback, depending on the choosen join style */ if (__TUBE_CUT_JOIN) { join_style_is_cut = TRUE; cap_callback = draw_cut_style_cap_callback; } else { join_style_is_cut = FALSE; cap_callback = draw_round_style_cap_callback; } /* By definition, the contour passed in has its up vector pointing in * the y direction */ if (up == NULL) { yup[0] = 0.0; yup[1] = 1.0; yup[2] = 0.0; } else { VEC_COPY (yup, up); } /* ========== "up" vector sanity check ========== */ (void) up_sanity_check (yup, npoints, point_array); /* the origin is at the origin */ origin [0] = 0.0; origin [1] = 0.0; origin [2] = 0.0; /* and neg_z is at neg z */ neg_z[0] = 0.0; neg_z[1] = 0.0; neg_z[2] = 1.0; /* malloc the data areas that we'll need to store the end-caps */ mem_anchor = malloc (4 * 3*ncp*sizeof(gleDouble) + 2 * 3*ncp*sizeof(double) + 2 * 1*ncp*sizeof(int)); front_norm = (double *) mem_anchor; back_norm = front_norm + 3*ncp; front_loop = (gleDouble *) (back_norm + 3*ncp); back_loop = front_loop + 3*ncp; front_cap = back_loop + 3*ncp; back_cap = front_cap + 3*ncp; front_is_trimmed = (int *) (back_cap + 3*ncp); back_is_trimmed = front_is_trimmed + ncp; /* ======================================= */ /* |-|-|-|-|-|-|-|-| SET UP FOR FIRST SEGMENT |-|-|-|-|-|-|-| */ /* ignore all segments of zero length */ i = 1; inext = i; FIND_NON_DEGENERATE_POINT (inext, npoints, seg_len, diff, point_array); tube_len = seg_len; /* store for later use */ /* may as well get the normals set up now */ if (cont_normal != NULL) { if (xform_array == NULL) { norm_loop = front_norm; back_norm = norm_loop; for (j=0; j 0.0)) { */ VEC_COPY ((&front_cap[3*j]), (&front_loop [3*j])); VEC_COPY ((&front_loop[3*j]), isect_point); front_is_trimmed[j] = TRUE; } else { front_is_trimmed[j] = FALSE; } /* if intersection is behind the end of the segment, * truncate to the end of the segment * Note that coding front_loop [3*j+2] = -tube_len; * doesn't work when twists are involved, */ if (front_loop[3*j+2] < -tube_len) { VEC_COPY( (&front_loop[3*j]), end_point_1); } /* --------------------------------------------------- */ /* The two end-points define a line. We did one endpoint * above. Now do the other.Intersect this line * against the clipping plane defined by the NEXT * tube segment. */ /* if this and the last tube are co-linear, don't cut the angle * if you do, a divide by zero will result. This and last tube * are co-linear when the cut vector is of zero length */ if (valid_cut_1 && join_style_is_cut) { INNERSECT (isect_point, /* isect point (returned) */ neg_z, /* point on intersecting plane */ lcut_1, /* normal vector to plane */ end_point_1, /* point on line */ end_point_0); /* another point on the line */ if (lcut_1[2] > 0.0) { VEC_SCALE (lcut_1, -1.0, lcut_1); } dot = lcut_1[0] * end_point_1[0]; dot += lcut_1[1] * end_point_1[1]; VEC_COPY ((&back_loop[3*j]), isect_point); } else { /* actual value of dot not interseting; need * only be positive so that if test below failes */ dot = 1.0; VEC_COPY ((&back_loop[3*j]), end_point_1); } INNERSECT (isect_point, /* intersection point (returned) */ neg_z, /* point on intersecting plane */ bisector_1, /* normal vector to plane */ torsion_point_0, /* point on line */ end_point_1); /* another point on the line */ /* cut out interior of intersecting tube */ /* ... but save the uncut version for drawing the endcaps */ /* ... note that cap contains valid data ONLY when is *_trimmed is TRUE. */ /* if ((dot <= 0.0) || (back_loop[3*j+2] < -tube_len)) { */ if ((dot <= 0.0) || (isect_point[2] > back_loop[3*j+2])) { VEC_COPY ((&back_cap[3*j]), (&back_loop [3*j])); VEC_COPY ((&back_loop[3*j]), isect_point); back_is_trimmed[j] = TRUE; } else { back_is_trimmed[j] = FALSE; } /* if intersection is behind the end of the segment, * truncate to the end of the segment * Note that coding back_loop [3*j+2] = 0.0; * doesn't work when twists are involved, */ if (back_loop[3*j+2] > 0.0) { VEC_COPY( (&back_loop[3*j]), end_point_0); } } /* --------- END OF TMESH GENERATION -------------- */ /* |||||||||||||||||| START SEGMENT DRAW |||||||||||||||||||| */ /* There are six different cases we can have for presence and/or * absecnce of colors and normals, and for interpretation of * normals. The blechy set of nested if statements below * branch to each of the six cases */ if (xform_array == NULL) { if (color_array == NULL) { if (cont_normal == NULL) { draw_segment_plain (ncp, (gleVector *) front_loop, (gleVector *) back_loop, inext, seg_len); } else if (__TUBE_DRAW_FACET_NORMALS) { draw_segment_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, inext, seg_len); } else { draw_segment_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, inext, seg_len); } } else { if (cont_normal == NULL) { draw_segment_color (ncp, (gleVector *) front_loop, (gleVector *) back_loop, color_array[inext-1], color_array[inext], inext, seg_len); } else if (__TUBE_DRAW_FACET_NORMALS) { draw_segment_c_and_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, color_array[inext-1], color_array[inext], inext, seg_len); } else { draw_segment_c_and_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, color_array[inext-1], color_array[inext], inext, seg_len); } } } else { if (color_array == NULL) { if (cont_normal == NULL) { draw_segment_plain (ncp, (gleVector *) front_loop, (gleVector *) back_loop, inext, seg_len); } else if (__TUBE_DRAW_FACET_NORMALS) { draw_binorm_segment_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) front_norm, (gleVector *) back_norm, inext, seg_len); } else { draw_binorm_segment_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) front_norm, (gleVector *) back_norm, inext, seg_len); } } else { if (cont_normal == NULL) { draw_segment_color (ncp, (gleVector *) front_loop, (gleVector *) back_loop, color_array[inext-1], color_array[inext], inext, seg_len); } else if (__TUBE_DRAW_FACET_NORMALS) { draw_binorm_segment_c_and_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) front_norm, (gleVector *) back_norm, color_array[inext-1], color_array[inext], inext, seg_len); } else { draw_binorm_segment_c_and_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) front_norm, (gleVector *) back_norm, color_array[inext-1], color_array[inext], inext, seg_len); } } } /* |||||||||||||||||| END SEGMENT DRAW |||||||||||||||||||| */ /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ /* if end caps are required, draw them. But don't draw any * but the very first and last caps */ if (first_time) { first_time = FALSE; tmp_cap_callback = cap_callback; cap_callback = null_cap_callback; if (__TUBE_DRAW_CAP) { if (color_array != NULL) C3F (color_array[inext-1]); draw_angle_style_front_cap (ncp, bisector_0, (gleVector *) front_loop); } } /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ /* $$$$$$$$$$$$$$$$ BEGIN -1, FILLET & JOIN DRAW $$$$$$$$$$$$$$$$$ */ /* * Now, draw the fillet triangles, and the join-caps. */ if (color_array != NULL) { front_color = color_array[inext-1]; back_color = color_array[inext]; } else { front_color = NULL; back_color = NULL; } if (cont_normal == NULL) { /* the flag valid-cut is true if the cut vector has a valid * value (i.e. if a degenerate case has not occured). */ if (valid_cut_0) { cut_vec = lcut_0; } else { cut_vec = NULL; } draw_fillets_and_join_plain (ncp, (gleVector *) front_loop, (gleVector *) front_cap, front_is_trimmed, origin, bisector_0, front_color, back_color, cut_vec, TRUE, cap_callback); /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ if (inext == npoints-2) { if (__TUBE_DRAW_CAP) { if (color_array != NULL) C3F (color_array[inext]); draw_angle_style_back_cap (ncp, bisector_1, (gleVector *) back_loop); cap_callback = null_cap_callback; } } else { /* restore ability to draw cap */ cap_callback = tmp_cap_callback; } /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ /* the flag valid-cut is true if the cut vector has a valid * value (i.e. if a degenerate case has not occured). */ if (valid_cut_1) { cut_vec = lcut_1; } else { cut_vec = NULL; } draw_fillets_and_join_plain (ncp, (gleVector *) back_loop, (gleVector *) back_cap, back_is_trimmed, neg_z, bisector_1, back_color, front_color, cut_vec, FALSE, cap_callback); } else { /* the flag valid-cut is true if the cut vector has a valid * value (i.e. if a degenerate case has not occured). */ if (valid_cut_0) { cut_vec = lcut_0; } else { cut_vec = NULL; } draw_fillets_and_join_n_norms (ncp, (gleVector *) front_loop, (gleVector *) front_cap, front_is_trimmed, origin, bisector_0, (gleVector *) front_norm, front_color, back_color, cut_vec, TRUE, cap_callback); /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ if (inext == npoints-2) { if (__TUBE_DRAW_CAP) { if (color_array != NULL) C3F (color_array[inext]); draw_angle_style_back_cap (ncp, bisector_1, (gleDouble (*)[3]) back_loop); cap_callback = null_cap_callback; } } else { /* restore ability to draw cap */ cap_callback = tmp_cap_callback; } /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ /* the flag valid-cut is true if the cut vector has a valid * value (i.e. if a degenerate case has not occured). */ if (valid_cut_1) { cut_vec = lcut_1; } else { cut_vec = NULL; } draw_fillets_and_join_n_norms (ncp, (gleVector *) back_loop, (gleVector *) back_cap, back_is_trimmed, neg_z, bisector_1, (gleVector *) back_norm, back_color, front_color, cut_vec, FALSE, cap_callback); } /* $$$$$$$$$$$$$$$$ END FILLET & JOIN DRAW $$$$$$$$$$$$$$$$$ */ /* pop this matrix, do the next set */ POPMATRIX (); /* slosh stuff over to next vertex */ tmp = front_norm; front_norm = back_norm; back_norm = tmp; tube_len = seg_len; i = inext; inext = inextnext; VEC_COPY (bi_0, bi_1); VEC_COPY (cut_0, cut_1); valid_cut_0 = valid_cut_1; /* reflect the up vector in the bisecting plane */ VEC_REFLECT (yup, yup, bi_0); } /* |-|-|-|-|-|-|-|-| END LOOP OVER SEGMENTS |-|-|-|-|-|-|-| */ free (mem_anchor); } /* =================== END OF FILE =============================== */ mgltools-gle-1.5.7~rc1~cvs.20130519/src/ex_angle.c0000644000175000017500000005260510061374075020530 0ustar debiandebian /* * MODULE NAME: ex_angle.c * * FUNCTION: * This module contains code that draws extrusions with angled * joins ("angle join style"). It also inserts colors and normals * where necessary, if appropriate. * * HISTORY: * written by Linas Vepstas August/September 1991 * split into multiple compile units, Linas, October 1991 * added normal vectors Linas, October 1991 * "code complete" (that is, I'm done), Linas Vepstas, October 1991 * work around OpenGL's lack of support for concave polys, June 1994 * * Copyright (C) 1991,1994,2003 Linas Vepstas */ #include #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" #include "segment.h" /* ============================================================ */ /* * Algorithmic trivia: * * There is a slight bit of trivia which the super-duper exacto coder * needs to know about the code in this module. It is this: * * This module attempts to correctly treat contour normal vectors * by applying the inverse transpose of the 2D contour affine * transformation to the 2D contour normals. This is perfectly correct, * when applied to the "raw" join style. However, if the affine transform * has a strong rotational component, AND the join style is angle or * cut, then the normal vectors would continue to rotate as the * intersect point is extrapolated. * * The extrapolation of the inverse-transpose matrix to the intersection * point is not done. This would appear to be overkill for most * situations. The viewer might possibly detect an artifact of the * failure to do this correction IF all three of the following criteria * were met: * 1) The affine xform has a strong rotational component, * 2) The angle between two succesive segments is sharp (greater than 15 or * 30 degrees). * 3) The join style is angle or cut. * * However, I beleive that it is highly unlikely that the viewer will * detect any artifacts. The reason I beleive this is that a strong * rotational component will twist a segment so strongly that the more * visible artifact will be that a segment is composed of triangle strips. * As the user attempts to minimize the tesselation artifacts by shortening * segments, then the rotational component will decrease in proportion, * and the lighting artifact will fall away. * * To summarize, there is a slight inexactness in this code. The author * of the code beleives that this inexactness results in miniscule * errors in every situation. * * Linas Vepstas March 1993 */ #ifndef COLOR_SIGNATURE /* ============================================================ */ void draw_angle_style_front_cap (int ncp, /* number of contour points */ gleDouble bi[3], /* biscetor */ gleDouble point_array[][3]) /* polyline */ { int j; #ifdef OPENGL_10 GLUtriangulatorObj *tobj; #ifdef DELICATE_TESSELATOR int is_colinear; double *previous_vertex = 0x0; double *first_vertex = 0x0; #endif /* DELICATE_TESSELATOR */ #endif /* OPENGL_10 */ if (bi[2] < 0.0) { VEC_SCALE (bi, -1.0, bi); } #ifdef GL_32 /* old-style gl handles concave polygons no problem, so the code is * simple. New-style gl is a lot more tricky. */ /* draw the end cap */ BGNPOLYGON (); N3F (bi); for (j=0; j 0.0) { VEC_SCALE (bi, -1.0, bi); } #ifdef GL_32 /* old-style gl handles concave polygons no problem, so the code is * simple. New-style gl is a lot more tricky. */ /* draw the end cap */ BGNPOLYGON (); N3F (bi); for (j=ncp-1; j>=0; j--) { V3F (point_array[j], j, BACK_CAP); } ENDPOLYGON (); #endif /* GL_32 */ #ifdef OPENGL_10 N3F (bi); tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); #ifdef LENIENT_TESSELATOR gluBeginPolygon (tobj); for (j=ncp-1; j>=0; j--) { gluTessVertex (tobj, point_array[j], point_array[j]); } gluEndPolygon (tobj); #endif /* LENIENT_TESSELATOR */ #ifdef DELICATE_TESSELATOR gluBeginPolygon (tobj); first_vertex = 0x0; previous_vertex = point_array[0]; for (j=ncp-1; j>0; j--) { COLINEAR (is_colinear, previous_vertex, point_array[j], point_array[j-1]); if (!is_colinear) { gluTessVertex (tobj, point_array[j], point_array[j]); previous_vertex = point_array[j]; if (!first_vertex) first_vertex = previous_vertex; } } if (!first_vertex) first_vertex = point_array[ncp-1]; COLINEAR (is_colinear, previous_vertex, point_array[0], first_vertex); if (!is_colinear) gluTessVertex (tobj, point_array[0], point_array[0]); gluEndPolygon (tobj); #endif /* DELICATE_TESSELATOR */ gluDeleteTess (tobj); #endif /* OPENGL_10 */ } #endif /* COLOR_SIGNATURE */ /* ============================================================ */ void extrusion_angle_join (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble cont_normal[][2], /* 2D normal vecs */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[][3], /* polyline */ gleColor color_array[], /* color of polyline */ gleDouble xform_array[][2][3]) /* 2D contour xforms */ { int i, j; int inext, inextnext; gleDouble m[4][4]; gleDouble len; gleDouble len_seg; gleDouble diff[3]; gleDouble bi_0[3], bi_1[3]; /* bisecting plane */ gleDouble bisector_0[3], bisector_1[3]; /* bisecting plane */ gleDouble end_point_0[3], end_point_1[3]; gleDouble origin[3], neg_z[3]; gleDouble yup[3]; /* alternate up vector */ gleDouble *front_loop, *back_loop; /* contours in 3D */ char * mem_anchor; double *norm_loop; double *front_norm, *back_norm, *tmp; /* contour normals in 3D */ int first_time; /* By definition, the contour passed in has its up vector pointing in * the y direction */ if (up == NULL) { yup[0] = 0.0; yup[1] = 1.0; yup[2] = 0.0; } else { VEC_COPY(yup, up); } /* ========== "up" vector sanity check ========== */ (void) up_sanity_check (yup, npoints, point_array); /* the origin is at the origin */ origin [0] = 0.0; origin [1] = 0.0; origin [2] = 0.0; /* and neg_z is at neg z */ neg_z[0] = 0.0; neg_z[1] = 0.0; neg_z[2] = 1.0; /* ignore all segments of zero length */ i = 1; inext = i; FIND_NON_DEGENERATE_POINT (inext, npoints, len, diff, point_array); len_seg = len; /* store for later use */ /* get the bisecting plane */ bisecting_plane (bi_0, point_array[0], point_array[1], point_array[inext]); /* reflect the up vector in the bisecting plane */ VEC_REFLECT (yup, yup, bi_0); /* malloc the storage we'll need for relaying changed contours to the * drawing routines. */ mem_anchor = malloc (2 * 3 * ncp * sizeof(double) + 2 * 3 * ncp * sizeof(gleDouble)); front_loop = (gleDouble *) mem_anchor; back_loop = front_loop + 3 * ncp; front_norm = (double *) (back_loop + 3 * ncp); back_norm = front_norm + 3 * ncp; norm_loop = front_norm; /* may as well get the normals set up now */ if (cont_normal != NULL) { if (xform_array == NULL) { for (j=0; j header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_STDINT_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Name of package */ #define PACKAGE "gle" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" /* Define to the version of this package. */ #define PACKAGE_VERSION "" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "3.1.0" /* Define to 1 if the X Window System is missing or not being used. */ /* #undef X_DISPLAY_MISSING */ mgltools-gle-1.5.7~rc1~cvs.20130519/LICENSE0000644000175000017500000000436411033241677017020 0ustar debiandebianThis software is copyrighted by Michel F. Sanner (sanner@scripps.edu) and TSRI. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. MGLTOOLS SOFTWARE LICENSE AGREEMENT. 1. Grant Of Limited License; Software Use Restrictions. The programs received by you will be used only for NON COMMERCIAL purposes. This license is issued to you as an individual. For COMMERCIAL use done with the software please contact Michel F. Sanner for details about commercial usage license agreements. For any question regarding license agreements, please contact Michel Sanner: TSRI, Molecular Biology Department, TCP 26, 10550 North Torrey Pines Road, La Jolla, CA 92037 sanner@scripps.edu tel (858) 784-7742 fax (858) 784-2341 2. COMMERCIAL USAGE is defined as revenues generating activities. These include using this software for consulting activities and selling applications built on top of, or using this software. Scientific research in an academic environment and teaching are considered NON COMMERCIAL. 3. Copying Restrictions. You will not sell or otherwise distribute commercially these programs or derivatives to any other party, whether with or without consideration. 4. Ownership of Software. You will not obtain, and will not attempt to obtain copyright coverage thereon without the express purpose written consent of The Scripps Research Institute and Dr. Sanner. 5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. mgltools-gle-1.5.7~rc1~cvs.20130519/version.py0000644000175000017500000000002011475262470020037 0ustar debiandebianVERSION="1.5.6" mgltools-gle-1.5.7~rc1~cvs.20130519/README0000644000175000017500000000243310260336150016656 0ustar debiandebianThis module builds a python extension of GLE library(version 3.1.0). GLE is a library package of C functions that draw extruded surfaces, including surfaces of revolution, sweeps, tubes, polycones, polycylinders and helicoids. Generically, the extruded surface is specified with a 2D polyline that is extruded along a 3D path. A local coordinate system allows for additional flexibility in the primitives drawn. Extrusions may be texture mapped in a variety of ways. The GLE library generates 3D triangle coordinates, lighting normal vectors and texture coordinates as output. GLE uses the GL or OpenGL(R) API's to perform the actual rendering. The package contains the GLE source code (./src). Building the extensions requires SWIG (version 1.3.20 or higher). To build the extensions and install the package: python2.4 setup.py install This will build _gle.so and gle.py(python shadow classes) in ./build/lib./gle, and install gle package in sys.exec_prefix/lib/python2.4/site-packages/. To specify an installation directory (INSTALL_DIR): python2.4 setup.py install --install-platlib=INSTALL_DIR To build the extension only: python2.4 setup.py build This will create ./build directory and build the extension there. To create a distribution: python2.4 setup.py sdist mgltools-gle-1.5.7~rc1~cvs.20130519/gle/0000755000175000017500000000000012146210056016544 5ustar debiandebianmgltools-gle-1.5.7~rc1~cvs.20130519/gle/gle.i0000644000175000017500000004525711165214476017514 0ustar debiandebian %module gle /**%include NumericArrays.i **/ %include numarr.i %{ #ifdef _MSC_VER #include #define WinVerMajor() LOBYTE(LOWORD(GetVersion())) #endif #include "gle.h" %} /* * gle.h * * FUNCTION: * Tubing and Extrusion header file. * This file provides protypes and defines for the extrusion * and tubing primitives. * * HISTORY: * Linas Vepstas 1990, 1991 */ #ifndef __GLE_H__ #define __GLE_H__ /* some types */ /* some types */ /*#define __GLE_DOUBLE 1 #if __GLE_DOUBLE typedef double gleDouble; #else typedef float gleDouble; #endif*/ #define gleDouble double typedef gleDouble gleAffine[2][3]; /* ====================================================== */ /* defines for tubing join styles */ #define TUBE_JN_RAW 0x1 #define TUBE_JN_ANGLE 0x2 #define TUBE_JN_CUT 0x3 #define TUBE_JN_ROUND 0x4 #define TUBE_JN_MASK 0xf /* mask bits */ #define TUBE_JN_CAP 0x10 /* determine how normal vectors are to be handled */ #define TUBE_NORM_FACET 0x100 #define TUBE_NORM_EDGE 0x200 #define TUBE_NORM_PATH_EDGE 0x400 /* for spiral, lathe, helix primitives */ #define TUBE_NORM_MASK 0xf00 /* mask bits */ /* closed or open countours */ #define TUBE_CONTOUR_CLOSED 0x1000 #define GLE_TEXTURE_ENABLE 0x10000 #define GLE_TEXTURE_STYLE_MASK 0xff #define GLE_TEXTURE_VERTEX_FLAT 1 #define GLE_TEXTURE_NORMAL_FLAT 2 #define GLE_TEXTURE_VERTEX_CYL 3 #define GLE_TEXTURE_NORMAL_CYL 4 #define GLE_TEXTURE_VERTEX_SPH 5 #define GLE_TEXTURE_NORMAL_SPH 6 #define GLE_TEXTURE_VERTEX_MODEL_FLAT 7 #define GLE_TEXTURE_NORMAL_MODEL_FLAT 8 #define GLE_TEXTURE_VERTEX_MODEL_CYL 9 #define GLE_TEXTURE_NORMAL_MODEL_CYL 10 #define GLE_TEXTURE_VERTEX_MODEL_SPH 11 #define GLE_TEXTURE_NORMAL_MODEL_SPH 12 #ifdef GL_32 /* HACK for GL 3.2 -- needed because no way to tell if lighting is on. */ #define TUBE_LIGHTING_ON 0x80000000 #define gleExtrusion extrusion #define gleSetJoinStyle setjoinstyle #define gleGetJoinStyle getjoinstyle #define glePolyCone polycone #define glePolyCylinder polycylinder #define gleSuperExtrusion super_extrusion #define gleTwistExtrusion twist_extrusion #define gleSpiral spiral #define gleLathe lathe #define gleHelicoid helicoid #define gleToroid toroid #define gleScrew screw #endif /* GL_32 */ #ifdef _NO_PROTO /* NO ANSI C PROTOTYPING */ extern int gleGetJoinStyle (); extern void gleSetJoinStyle (); extern void glePolyCone (); extern void glePolyCylinder (); extern void gleExtrusion (); extern void gleSuperExtrusion (); extern void gleTwistExtrusion (); extern void gleSpiral (); extern void gleLathe (); extern void gleHelicoid (); extern void gleToroid (); extern void gleScrew (); #else /* _NO_PROTO */ /* ANSI C PROTOTYPING */ extern void gleDestroyGC (void); /* control join style of the tubes */ extern int gleGetJoinStyle (void); extern void gleSetJoinStyle (int style); /* bitwise OR of flags */ /* control number of sides used to draw cylinders, cones */ extern int gleGetNumSides(void); extern void gleSetNumSides(int slices); /* typemaps for Numeric arrays */ DOUBLE_ARRAY2D( point_array, [1][3], npoints ) %apply float ARRAY2D_NULL[ANY][ANY] { float color_array[1][3] } /* draw polycylinder, specified as a polyline */ extern void glePolyCylinder (int npoints, /* num points in polyline */ gleDouble point_array[1][3], /* polyline vertces */ float color_array[1][3], /* colors at polyline verts */ gleDouble radius); /* radius of polycylinder */ extern void glePolyCylinder_c4f (int npoints, /* num points in polyline */ gleDouble point_array[1][3], /* polyline vertces */ gleColor4f color_array[1], /* colors at polyline verts */ gleDouble radius); /* radius of polycylinder */ /* typemaps for Numeric arrays */ %apply double VECTOR[ANY] { double radius_array[1] }; /* draw polycone, specified as a polyline with radii */ extern void glePolyCone (int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ float color_array[1][3], /* colors at polyline verts */ gleDouble radius_array[1]); /* cone radii at polyline verts */ extern void glePolyCone_c4f (int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ gleColor4f color_array[1], /* colors at polyline verts */ gleDouble radius_array[1]); /* cone radii at polyline verts */ #typemaps for Numeric arrays DOUBLE_ARRAY2D( contour, [1][2], ncp ) %apply double ARRAY2D[ANY][ANY] { double cont_normal[1][2] }; %apply double VECTOR_NULL[ANY] { double up[3] }; /* extrude arbitrary 2D contour along arbitrary 3D path */ extern void gleExtrusion (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ float color_array[1][3]); /* colors at polyline verts */ extern void gleExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ gleColor4f color_array[1]); /* colors at polyline verts */ #typemaps for Numeric arrays %apply double VECTOR[ANY] { double twist_array[1] }; /* extrude 2D contour, specifying local rotations (twists) */ extern void gleTwistExtrusion (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ float color_array[1][3], /* color at polyline verts */ gleDouble twist_array[1]); /* countour twists (in degrees) */ extern void gleTwistExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ gleColor4f color_array[1], /* color at polyline verts */ gleDouble twist_array[1]); /* countour twists (in degrees) */ #typemaps for Numeric arrays %apply double ARRAY3D_NULL[ANY][ANY][ANY] { double xform_array[1][2][3] }; /* extrude 2D contour, specifying local affine tranformations */ extern void gleSuperExtrusion (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ float color_array[1][3], /* color at polyline verts */ gleDouble xform_array[1][2][3]); /* 2D contour xforms */ extern void gleSuperExtrusion_c4f (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal1[][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ int npoints, /* numpoints in poly-line */ gleDouble point_array[1][3], /* polyline vertices */ gleColor4f color_array[1], /* color at polyline verts */ gleDouble xform_array[1][2][3]); /* 2D contour xforms */ #typemaps for Numeric arrays %apply double ARRAY2D_NULL[ANY][ANY] { double startXform[2][3] }; %apply double ARRAY2D_NULL[ANY][ANY] { double dXformdTheta[2][3] }; /* spiral moves contour along helical path by parallel transport */ extern void gleSpiral (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* lathe moves contour along helical path by helically shearing 3D space */ extern void gleLathe (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* similar to spiral, except contour is a circle */ extern void gleHelicoid (gleDouble rToroid, /* circle contour (torus) radius */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* similar to lathe, except contour is a circle */ extern void gleToroid (gleDouble rToroid, /* circle contour (torus) radius */ gleDouble startRadius, /* spiral starts in x-y plane */ gleDouble drdTheta, /* change in radius per revolution */ gleDouble startZ, /* starting z value */ gleDouble dzdTheta, /* change in Z per revolution */ gleDouble startXform[2][3], /* starting contour affine xform */ gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ gleDouble startTheta, /* start angle in x-y plane */ gleDouble sweepTheta); /* degrees to spiral around */ /* draws a screw shape */ extern void gleScrew (int ncp, /* number of contour points */ gleDouble contour[1][2], /* 2D contour */ gleDouble cont_normal[1][2], /* 2D contour normals */ gleDouble up[3], /* up vector for contour */ gleDouble startz, /* start of segment */ gleDouble endz, /* end of segment */ gleDouble twist); /* number of rotations */ extern void gleTextureMode (int mode); /* typmaps for Numeric arrays */ %apply double VECTOR[ANY] { double axis[3]}; %apply double ARRAY2D[ANY][ANY] {double m[4][4]}; /* Rotation Utilities */ extern void rot_axis (gleDouble omega, gleDouble axis[3]); extern void rot_about_axis (gleDouble angle, gleDouble axis[3]); extern void rot_omega (gleDouble axis[3]); extern void rot_prince (gleDouble omega, char axis); extern void urot_axis (gleDouble m[4][4], gleDouble omega, gleDouble axis[3]); extern void urot_about_axis (gleDouble m[4][4], gleDouble angle, gleDouble axis[3]); extern void urot_omega (gleDouble m[4][4], gleDouble axis[3]); extern void urot_prince (gleDouble m[4][4], gleDouble omega, char axis); /* typmaps for Numeric arrays */ %apply double VECTOR[ANY]{double v21[3]}; %apply double VECTOR[ANY]{double up[3]}; %apply double VECTOR[ANY]{double v1[3]}; %apply double VECTOR[ANY]{double v2[3]}; /* viewpoint functions */ extern void uview_direction (gleDouble m[4][4], /* returned */ gleDouble v21[3], /* input */ gleDouble up[3]); /* input */ extern void uviewpoint (gleDouble m[4][4], /* returned */ gleDouble v1[3], /* input */ gleDouble v2[3], /* input */ gleDouble up[3]); /* input */ #endif /* _NO_PROTO */ #endif /* __GLE_H__ */ /* ================== END OF FILE ======================= */ %{ /** #include **/ #include #include "port.h" #include "tube_gc.h" void _gleFeedback ( void (*bgn_feedback) (int, double), void (*n3d_feedback) (double *), void (*v3d_feedback) (double *, int, int), void (*end_feedback) () ) { INIT_GC(); _gle_gc -> bgn_gen_texture = bgn_feedback; _gle_gc -> n3d_gen_texture = n3d_feedback; _gle_gc -> v3d_gen_texture = v3d_feedback; _gle_gc -> end_gen_texture = end_feedback; } #include static int nbpts = 0; static int max_nbpts = 0; static int nbnorm = 0; static int max_norm = 0; static int nbstrip = 0; static int max_strip = 0; static double *vertices = NULL; static double *normals = NULL; static int *strips = NULL; double *growDouble(double *array, int n, int *max, int dim) { double *p; /* fixme ... catch memory allocation error, return error code */ (*max) += n; p = (double *)realloc( array, (*max)*dim*sizeof(double)); /* printf("allocate %d %p\n", (*max), p ); */ return p; } int *growInt(int *array, int n, int *max, int dim) { int *p; /* fixme ... catch memory allocation error, return error code */ (*max) += n; p = (int *)realloc( array, (*max)*dim*sizeof(int)); /* printf("allocate %d %p\n", (*max), p ); */ return p; } static void add_Vertex(double v[3]) { if (nbpts >= max_nbpts) vertices = growDouble(vertices, 1000, &max_nbpts, 3); vertices[nbpts*3] = v[0]; vertices[(nbpts*3)+1] = v[1]; vertices[(nbpts*3)+2] = v[2]; /*printf("V %d %d %p, %g %g %g\n", nbpts, max_nbpts, vertices, vertices[nbpts*3], vertices[(nbpts*3)+1], vertices[(nbpts*3)+2]);*/ nbpts++; } static void add_Normal(double v[3]) { if (nbnorm >= max_norm) normals = growDouble(normals, 1000, &max_norm, 3); normals[nbnorm*3] = v[0]; normals[(nbnorm*3)+1] = v[1]; normals[(nbnorm*3)+2] = v[2]; /* printf("N %d %d %p %g %g %g\n", nbnorm, max_norm, normals, normals[nbnorm*3], normals[(nbnorm*3)+1], normals[(nbnorm*3)+2]); */ nbnorm++; } #ifdef __APPLE__ #include #else #include #endif static void add_Strip() { /* printf("addStrip %d %d %d\n", nbstrip, nbpts, nbnorm); */ if (nbstrip >= max_strip) strips = growInt(strips, 100, &max_strip, 2); strips[nbstrip*2] = nbpts; strips[(nbstrip*2)+1] = nbnorm; /* printf("addStrip %d %d %d\n", nbstrip, strips[nbstrip*2], strips[(nbstrip*2)+1]); */ nbstrip++; } static double _mat_[16]; static void bgn_feedback (int inext, double len) { int i; glGetDoublev(GL_MODELVIEW_MATRIX, (double *)_mat_); /* printf("Begin mod "); for (i=0; i<16; i++) printf("%7.3f",_mat_[i]); printf("\n");*/ } static void end_feedback () { add_Strip(); } static void multmat(double v[3], double mat[16], double vm[3], int homo) { int i; vm[0] = mat[0]*v[0] + mat[4]*v[1] + mat[8]*v[2] + homo*mat[12]; vm[1] = mat[1]*v[0] + mat[5]*v[1] + mat[9]*v[2] + homo*mat[13]; vm[2] = mat[2]*v[0] + mat[6]*v[1] + mat[10]*v[2] + homo*mat[14]; } static void normal_feedback (double v[3]) { GLdouble vt[3]; /* printf("n1 %lf %lf %lf\n", v[0], v[1], v[2]); */ multmat(v, _mat_, &vt[0], 0); /* printf("n2 %lf %lf %lf\n", vt[0], vt[1], vt[2]); */ /* printf("%lf %lf %lf\n", vt[0], vt[1], vt[2]); */ add_Normal(vt); } static void vertex_feedback (double v[3], int jcnt, int end) { GLdouble vt[3]; /* printf("v %lf %lf %lf\n", v[0], v[1], v[2]); */ multmat(v, _mat_, &vt[0], 1); /* printf("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n", v[0], v[1], v[2], vt[0], vt[1], vt[2]); */ add_Vertex(vt); } %} %inline %{ void gleFeedBack() { nbpts = nbnorm = nbstrip = max_nbpts = max_norm = max_strip = 0; _gleFeedback(bgn_feedback, normal_feedback, vertex_feedback, end_feedback); } void gleFreeFeedbackBuffers() { /* if (vertices) free(vertices); if (normals) free(normals); if (strips) free(strips); */ } %} %{ static PyObject *gleGetTriangleMesh(PyObject *self, PyObject *args) { PyArrayObject *v_array, *n_array, *s_array; npy_intp dims[2]; dims[0] = nbpts; dims[1] = 3; v_array = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, (char *)vertices); #ifdef _MSC_VER switch ( WinVerMajor() ) { case 6: break; // Vista default: v_array->flags |= NPY_OWNDATA; } #else // so we'll free this memory when this // array will be garbage collected v_array->flags |= NPY_OWNDATA; #endif dims[0] = nbnorm; dims[1] = 3; n_array = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, (char *)normals); #ifdef _MSC_VER switch ( WinVerMajor() ) { case 6: break; // Vista default: n_array->flags |= NPY_OWNDATA; } #else // so we'll free this memory when this // array will be garbage collected n_array->flags |= NPY_OWNDATA; #endif dims[0] = nbstrip; dims[1] = 2; s_array = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, PyArray_INT, (char *)strips); #ifdef _MSC_VER switch ( WinVerMajor() ) { case 6: break; // Vista default: s_array->flags |= NPY_OWNDATA; } #else // so we'll free this memory when this // array will be garbage collected s_array->flags |= NPY_OWNDATA; #endif return Py_BuildValue("OOO", v_array, n_array, s_array); } %} %native(gleGetTriangleMesh) gleGetTriangleMesh; mgltools-gle-1.5.7~rc1~cvs.20130519/gle/numarr.i0000644000175000017500000001734210653454424020243 0ustar debiandebian/* This allows to insert the import_array() inti the module initialization code. This is required for versions of Python where RTLD+GLOBAL is disabled and the Numeric extension is not built into the kernel */ %init %{ import_array(); /* load the Numeric PyCObjects */ %} %{ #include "numpy/arrayobject.h" #define Get2D(arr, dims, i, j) arr[(i * dims[1]) + j] #define Get3D(arr, dims, i, j, k) arr[(i * dims[1] * dims[2]) + \ (j * dims[2]) + k] #define Get4D(arr, dims, i, j, k, l) arr[(i * dims[1] * dims[2] * dims[3]) + \ (j * dims[2] * dims[3]) + \ (k * dims[3]) + l] /******************************************************************** Tries to create a contiguous numeric array of type typecode from a Python object. Works for list, tuples and numeric arrays. obj: Numeric array Python object typecode: data type PyArray_{ CHAR, UBYTE, SBYTE, SHORT, INT, LONG, FLOAT, DOUBLE, CFLOAT, CDOUBLE } expectnd: required number of dimensions. Used for checking. Ignored if <=0. expectdims: array of expected extends. Used for checking. Ignored if <=0. Raises ValueError exceptions if: - the PyArray_ContiguousFromObject fails - the array has a bad shape - the extent of a given dimension doesn't match the specified extent. ********************************************************************/ static PyArrayObject *contiguous_typed_array(PyObject *obj, int typecode, int expectnd, int *expectdims) { PyArrayObject *arr; int i, numitems, itemsize; char buf[255]; /* if the shape and type are OK, this function increments the reference count and arr points to obj */ if((arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj, typecode, 0, 10)) == NULL) { sprintf(buf,"Failed to make a contiguous array of type %d\n", typecode); PyErr_SetString(PyExc_ValueError, buf); return NULL; } if(expectnd>0) { if(arr->nd > expectnd + 1 || arr->nd < expectnd) { Py_DECREF((PyObject *)arr); PyErr_SetString(PyExc_ValueError, "Array has wrong number of dimensions"); return NULL; } if(arr->nd == expectnd + 1) { if(arr->dimensions[arr->nd - 1] != 1) { Py_DECREF((PyObject *)arr); PyErr_SetString(PyExc_ValueError, "Array has wrong number of dimensions"); return NULL; } } if(expectdims) { for(i = 0; i < expectnd; i++) if(expectdims[i]>0) if(expectdims[i] != arr->dimensions[i]) { Py_DECREF((PyObject *)arr); sprintf(buf,"The extent of dimension %d is %d while %d was expected\n", i, arr->dimensions[i], expectdims[i]); PyErr_SetString(PyExc_ValueError, buf); return NULL; } } } return arr; } %} /*******************************************************/ /** Input: float ARRAY2D_NULL **/ /*******************************************************/ %typemap(in) float ARRAY2D_NULL[ANY][ANY] (PyArrayObject *array , int expected_dims[2]) { if ($input == Py_None) { $1 = NULL; } else { expected_dims[0] = $1_dim0; expected_dims[1] = $1_dim1; if (expected_dims[0]==1) expected_dims[0]=0; if (expected_dims[1]==1) expected_dims[1]=0; array = contiguous_typed_array($input, PyArray_FLOAT, 2, expected_dims); if (! array) return NULL; $1 = (float (*)[$1_dim1])array->data; } } /*******************************************************/ /** Input: double ARRAY2D_NULL **/ /*******************************************************/ %typemap(in) double ARRAY2D_NULL[ANY][ANY] (PyArrayObject *array , int expected_dims[2]) { if ($input == Py_None) { $1 = NULL; } else { expected_dims[0] = $1_dim0; expected_dims[1] = $1_dim1; if (expected_dims[0]==1) expected_dims[0]=0; if (expected_dims[1]==1) expected_dims[1]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 2, expected_dims); if (! array) return NULL; $1 = (double (*)[$1_dim1])array->data; } } /*************************************************************/ /* INPUT: double VECTOR */ /*************************************************************/ %typemap(in) double VECTOR[ANY] (PyArrayObject *array, int expected_dims[1]) %{ expected_dims[0] = $1_dim0; if (expected_dims[0]==1) expected_dims[0]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 1, expected_dims); if (! array) return NULL; $1 = (double *)array->data; %} %typemap(freearg) double VECTOR[ANY] %{ if ( array$argnum ) Py_DECREF((PyObject *)array$argnum); %} %typemap(in) double VECTOR_NULL[ANY] (PyArrayObject *array) { if ($input == Py_None) { $1 = NULL; } else { int expected_dims[1] = {$1_dim0}; if (expected_dims[0]==1) expected_dims[0]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 1, expected_dims); if (! array) return NULL; $1 = (double *)array->data; } } /*************************************************************/ /* INPUT: double ARRAY2D */ /*************************************************************/ %typemap(in) double ARRAY2D[ANY][ANY](PyArrayObject *array, int expected_dims[2]) %{ if ($input != Py_None) { expected_dims[0] = $1_dim0; expected_dims[1] = $1_dim1; if (expected_dims[0]==1) expected_dims[0]=0; if (expected_dims[1]==1) expected_dims[1]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 2, expected_dims); if (! array) return NULL; $1 = (double (*)[$1_dim1])array->data; } else { array = NULL; $1 = NULL; } %} %typemap(freearg) double ARRAY2D[ANY][ANY] %{ if ( array$argnum ) Py_DECREF((PyObject *)array$argnum); %} %typemap(python,in) double ARRAY3D_NULL[ANY][ANY][ANY] (PyArrayObject *array) { if ($input == Py_None) { $1 = NULL; } else { int expected_dims[3] = {$dim0, $dim1, $dim2}; if (expected_dims[0]==1) expected_dims[0]=0; if (expected_dims[1]==1) expected_dims[1]=0; if (expected_dims[2]==1) expected_dims[2]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 3, expected_dims); if (! array) return NULL; $1 = (double (*)[$1_dim1][$1_dim2])array->data; } } /**************************************************************/ /* Input: DOUBLE_ARRAY2D */ /**************************************************************/ %define DOUBLE_ARRAY2D( ARRAYNAME, ARRAYSHAPE, DIMENSIONS ) %typemap(in) ( int DIMENSIONS, double ARRAYNAME##ARRAYSHAPE)(PyArrayObject *array, int expected_dims[2]) %{ if ($input != Py_None) { expected_dims[0] = $2_dim0; expected_dims[1] = $2_dim1; if (expected_dims[0]==1) expected_dims[0]=0; if (expected_dims[1]==1) expected_dims[1]=0; array = contiguous_typed_array($input, PyArray_DOUBLE, 2, expected_dims); if (! array) return NULL; $2 = (double (*)[$2_dim1])array->data; $1 = ((PyArrayObject *)(array))->dimensions[0]; } else { array = NULL; $2 = NULL; $1 = 0; } %} %typemap(freearg) (int DIMENSIONS, double ARRAYNAME##ARRAYSHAPE) %{ if (array$argnum ) Py_DECREF((PyObject *)array$argnum); %} %enddef mgltools-gle-1.5.7~rc1~cvs.20130519/gle/Tests/0000755000175000017500000000000012146210056017646 5ustar debiandebianmgltools-gle-1.5.7~rc1~cvs.20130519/gle/Tests/__init__.py0000644000175000017500000000001510453016734021761 0ustar debiandebian#__init__.py mgltools-gle-1.5.7~rc1~cvs.20130519/gle/Tests/test_dependencies.py0000644000175000017500000000150610406105100023675 0ustar debiandebian# ################################################################# # Author: Sowjanya Karnati ################################################################# # #Purpose:To update dependencies list # # $Id: test_dependencies.py,v 1.2 2006/03/15 21:42:24 sowjanya Exp $ from mglutil.TestUtil.Tests.dependenciestest import DependencyTester import unittest d = DependencyTester() result_expected =[] class test_dep(unittest.TestCase): def test_dep_1(self): result = d.rundeptester('gle') if result !=[]: print "\nThe Following Packages are not present in CRITICAL or NONCRITICAL DEPENDENCIES of gle :\n %s" %result self.assertEqual(result,result_expected) else: self.assertEqual(result,result_expected) if __name__ == '__main__': unittest.main() mgltools-gle-1.5.7~rc1~cvs.20130519/gle/__init__.py0000644000175000017500000000024010473153337020662 0ustar debiandebianfrom gle import * import _gle as glec __MGLTOOLSVersion__ = '1-4alpha3' CRITICAL_DEPENDENCIES = ['opengltk', 'Numeric'] NONCRITICAL_DEPENDENCIES = ['mglutil'] mgltools-gle-1.5.7~rc1~cvs.20130519/gle/test.py0000644000175000017500000000721610653444127020114 0ustar debiandebian## Automatically adapted for numpy.oldnumeric Jul 30, 2007 by #test.py - an example program, (rewritten in python from the GLE distribution demo). from opengltk.OpenGL import GL, GLU, GLUT import gle import numpy.oldnumeric as Numeric import sys lastx=0 lasty=0 NPTS = 6 points = Numeric.zeros((NPTS, 3), "f") colors = Numeric.zeros((NPTS,3), "f") idx = 0 def PNT(x,y,z): global idx points[idx][0] = x points[idx][1] = y points[idx][2] = z idx = idx+1 def COL(r,g,b): global idx colors[idx][0] = r colors[idx][1] = g colors[idx][2] = b # * Initialize a bent shape with three segments. # * The data format is a polyline. # * # * NOTE that neither the first, nor the last segment are drawn. # * The first & last segment serve only to determine that angle # * at which the endcaps are drawn. def InitStuff (): # initialize the join style here gle.gleSetJoinStyle (gle.TUBE_NORM_EDGE | gle.TUBE_JN_ANGLE | gle.TUBE_JN_CAP) COL (0.0, 0.0, 0.0) PNT (-6.0, 6.0, 0.0) COL (0.0, 0.8, 0.3) PNT (6.0, 6.0, 0.0) COL (0.8, 0.3, 0.0) PNT (6.0, -6.0, 0.0) COL (0.2, 0.3, 0.9) PNT (-6.0, -6.0, 0.0) COL (0.2, 0.8, 0.5) PNT (-6.0, 6.0, 0.0) COL (0.0, 0.0, 0.0) PNT (6.0, 6.0, 0.0) #draw the cylinder shape def DrawStuff (): GL.glClear (GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) # set up some matrices so that the object spins with the mouse GL.glPushMatrix () GL.glTranslatef (0.0, 0.0, -80.0) GL.glRotatef (lastx, 0.0, 1.0, 0.0) GL.glRotatef (lasty, 1.0, 0.0, 0.0) # Phew. FINALLY, Draw the polycylinder -- #gle.glePolyCylinder (NPTS, points, colors, 2.3) gle.glePolyCylinder (points, colors, 2.3) GL.glPopMatrix () GLUT.glutSwapBuffers () # get notified of mouse motions def MouseMotion (x, y): lastx = x lasty = y GLUT.glutPostRedisplay () def keyboard( key, x, y): if 'e' == chr( key): raise RuntimeError elif 'q' == chr( key): sys.exit() def JoinStyle (msg): # get the current joint style style = gle.gleGetJoinStyle () # there are four different join styles, # * and two different normal vector styles normalStyle = gle.TUBE_NORM_PATH_EDGE joinStyle = gle.TUBE_JN_ANGLE gle.gleSetJoinStyle ( normalStyle | joinStyle ) GLUT.glutPostRedisplay () # set up a light lightOnePosition = [40.0, 40, 100.0, 0.0] lightOneColor = [0.99, 0.99, 0.99, 1.0] lightTwoPosition = [-40.0, 40, 100.0, 0.0] lightTwoColor = [0.99, 0.99, 0.99, 1.0] ### initialize glut GLUT.glutInit (sys.argv) GLUT.glutInitDisplayMode (GLUT.GLUT_DOUBLE | GLUT.GLUT_RGB | GLUT.GLUT_DEPTH) GLUT.glutCreateWindow ("join styles") GLUT.glutDisplayFunc (DrawStuff) #GLUT.glutMotionFunc (MouseMotion) # initialize GL GL.glClearDepth (1.0) GL.glEnable (GL.GL_DEPTH_TEST) GL.glClearColor (0.0, 0.0, 0.0, 0.0) GL.glShadeModel (GL.GL_SMOOTH) GL.glMatrixMode (GL.GL_PROJECTION) # roughly, measured in centimeters GL.glFrustum (-9.0, 9.0, -9.0, 9.0, 50.0, 150.0) GL.glMatrixMode(GL.GL_MODELVIEW) # initialize lighting GL.glLightfv (GL.GL_LIGHT0, GL.GL_POSITION, lightOnePosition) GL.glLightfv (GL.GL_LIGHT0, GL.GL_DIFFUSE, lightOneColor) GL.glEnable (GL.GL_LIGHT0) GL.glLightfv (GL.GL_LIGHT1, GL.GL_POSITION, lightTwoPosition) GL.glLightfv (GL.GL_LIGHT1, GL.GL_DIFFUSE, lightTwoColor) GL.glEnable (GL.GL_LIGHT1) GL.glEnable (GL.GL_LIGHTING) GL.glEnable (GL.GL_NORMALIZE) GL.glColorMaterial (GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE) GL.glEnable (GL.GL_COLOR_MATERIAL) InitStuff () GLUT.glutKeyboardFunc(keyboard) print "Type 'q' in the demo window to quit" GLUT.glutMainLoop () mgltools-gle-1.5.7~rc1~cvs.20130519/MANIFEST.in0000644000175000017500000000036511033242665017544 0ustar debiandebianinclude MANIFEST.in include version.py include src/*.h include src/COPYING.src include src/README.gutil include config.h exclude gle/gle.py include gle/*.i include CVS/* include gle/CVS/* include src/CVS/* include gle/doc.tar.gz include LICENSE