static void JoinStyle (int msg) { int style; /* get the current joint style */ style = gleGetJoinStyle (); /* there are four different join styles, * and two different normal vector styles */ switch (msg) { case 0: style &= ~TUBE_JN_MASK; style |= TUBE_JN_RAW; break; case 1: style &= ~TUBE_JN_MASK; style |= TUBE_JN_ANGLE; break; case 2: style &= ~TUBE_JN_MASK; style |= TUBE_JN_CUT; break; case 3: style &= ~TUBE_JN_MASK; style |= TUBE_JN_ROUND; break; case 20: style &= ~TUBE_NORM_MASK; style |= TUBE_NORM_FACET; break; case 21: style &= ~TUBE_NORM_MASK; style |= TUBE_NORM_EDGE; break; case 99: exit (0); default: break; } gleSetJoinStyle (style); glutPostRedisplay (); }
static void init_twist (void) { int js; init_toid1_line (); init_tripples (); #ifdef IBM_GL_32 js = getjoinstyle (); js &= ~TUBE_CONTOUR_CLOSED; setjoinstyle (js); #endif #ifdef OPENGL_10 js = gleGetJoinStyle (); js &= ~TUBE_CONTOUR_CLOSED; gleSetJoinStyle (js); #endif }
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); }