/* * 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 */ #include #include #include /* for the memcpy() subroutine */ #include /* to get stderr defined */ #include #include "port.h" #include "gutil.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" #include "segment.h" /* ============================================================ */ /* * 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 "official" error interface */ /* fprintf (stderr, "Extrusion: Warning: initial segment zero length \n"); */ /* 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=1; 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 */ } /* ============================================================ */ /* This routine does what it says: It draws a counter-clockwise cap * from a 3D contour loop list */ 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 */ void draw_raw_segment_plain (int ncp, /* number of contour points */ gleDouble contour[][2], /* 2D contour */ gleDouble len, int inext) { int j; double point[3]; /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j