/* * 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 #include "port.h" #include "gutil.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], float face_color[3], 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_d (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