/************************************************************************* * *N outline_face * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function outlines (without filling) the specified face from * the given face table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * face_id <input>==(ossim_int32) row id of the specified face. * facetable <input>==(vpf_table_type) VPF facemitive table. * ringtable <input>==(vpf_table_type) VPF ringmitive table. * edgetable <input>==(vpf_table_type) VPF edge primitive table. * outline <input>==(color_type) outline color. * inner <input>==(int) if TRUE, draw inner rings; * if FALSE, only draw outer ring. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ void outline_face( ossim_int32 face_id, vpf_table_type facetable, vpf_table_type ringtable, vpf_table_type edgetable, color_type outline, int inner ) { face_rec_type face_rec; ring_rec_type ring_rec; gpsetlinecolor(outline); gpsetlinestyle(SOLID_LINE); gpsetlinewidth(NORM_WIDTH); face_rec = read_face( face_id, facetable ); ring_rec = read_ring( face_rec.ring, ringtable ); outline_polygon_loop( face_id, ring_rec.edge, edgetable ); if (!inner) return; while (ring_rec.face == face_id ) { ring_rec = read_next_ring( ringtable ); if (feof(ringtable.fp)) { break; } if (ring_rec.face == face_id) { outline_polygon_loop( face_id, ring_rec.edge, edgetable ); } } }
/*************************************************************************** * *N point_in_face * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Test whether a line (x,y through infinity) intersects a face (which * itself is multiple polygon_loop or ring structures). Returns a 0 * if outside, 1 if inside. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * x <input> == (float) x coordinate of given point. * y <input> == (float) y coordinate of given point. * face_id <input> == (rspf_int32) given face. * facetable <input> == (vpf_table_type) VPF face table. * ringtable <input> == (vpf_table_type) VPF ring table. * edgetable <input> == (vpf_table_type) VPF edge table. * point_in_face <output> == (int) VPF_BOOLEAN: * 1 --> inside * 0 --> outside *E **************************************************************************/ int point_in_face( float x, float y, rspf_int32 face_id, vpf_table_type facetable, vpf_table_type ringtable, vpf_table_type edgetable ) { face_rec_type face_rec; ring_rec_type ring_rec; int n; face_rec = read_face( face_id, facetable ); ring_rec = read_ring( face_rec.ring, ringtable ); n = intersect_polygon_loop( x, y, face_id, ring_rec.edge, edgetable ); while (ring_rec.face == face_id ) { ring_rec = read_next_ring( ringtable ); if (feof(ringtable.fp)) { break; } if (ring_rec.face == face_id) { n += intersect_polygon_loop( x, y, face_id, ring_rec.edge, edgetable ); } } if (n%2 == 0) /* Even number of intersections */ return 0; /* Not inside polygon */ else /* Odd number of intersections */ return 1; /* Inside polygon */ }
/************************************************************************* * *N draw_polygon * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws a polygon for VPF face structure tables. * It is complicated by the fact that it checks to see whether * enough memory is available to draw the entire polygon in a * Shademap structure, or whether the face must be broken up into * smaller chunks so the bit arrays can fit into memory. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * mbrx1 <input> == (int) mbr corner 1 x coordinate. * mbry1 <input> == (int) mbr corner 1 y coordinate. * mbrx2 <input> == (int) mbr corner 2 x coordinate. * mbry2 <input> == (int) mbr corner 2 y coordinate. * face_rec <input> == (face_rec_type) * ringtable <input> == (vpf_table_type) VPF ring table. * edgetable <input> == (vpf_table_type) VPF edge table. * outline <input> == (color_type) polygon outline color. * pattern <input> == (Pattern) polygon fill pattern. * wrap <input> == (int) wrap around if the polygon wraps around * the screen. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ void draw_polygon( int mbrx1, int mbry1, int mbrx2, int mbry2, face_rec_type face_rec, vpf_table_type ringtable, vpf_table_type edgetable, color_type outline, Pattern pattern, int wrap ) { int x1,y1,x2,y2, nchunks,chunk,delta, ok, k; Shademap *poly; IBox bounding,wdw,make_ibox(); ring_rec_type ring_rec; x1 = mbrx1-2; y1 = mbry1-2; x2 = mbrx2+2; y2 = mbry2+2; delta = x2-x1; nchunks=1; wdw = make_ibox(0,0,gpgetmaxx()+1,gpgetmaxy()); bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; if (gpgetdevice() == SCREEN) { /* wdw = make_ibox(0,0,getmaxx()+1,getmaxy()); bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; */ ok = TRUE; if (!poly->Bordermap.array || !poly->Maskmap.array) { /* Not enough memory - Split polygon up */ if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap); if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap); free(poly); poly = (Shademap *)NULL; k = 2; delta = gpgetmaxx()/k; nchunks = (mbrx2-mbrx1)/delta + 1; ok = FALSE; while (!ok) { ok = TRUE; bounding = make_ibox(0,y1,delta,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; if (!poly->Bordermap.array || !poly->Maskmap.array) { ok = FALSE; if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap); if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap); free(poly); k++; delta = gpgetmaxx()/k; if (delta < 5) return; nchunks = (mbrx2-mbrx1)/delta + 1; } else { FreeArrayOfBits(poly->Bordermap); FreeArrayOfBits(poly->Maskmap); free(poly); poly = (Shademap *)NULL; } } x2 = x1 + delta; bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade(bounding,wdw,outline,pattern); } } for (chunk=0;chunk<nchunks;chunk++) { ring_rec = read_ring( face_rec.ring, ringtable ); draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable, poly, wrap ); gpcloseloop(poly); while (ring_rec.face == face_rec.id ) { ring_rec = read_next_ring( ringtable ); if (feof(ringtable.fp)) { gpcloseloop(poly); break; } if (ring_rec.face == face_rec.id) { draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable, poly, wrap ); gpcloseloop(poly); } } hidemousecursor(); gpfillpoly(poly); showmousecursor(); if (gpgetdevice()==SCREEN) { poly = (Shademap *)NULL; if (x2 < mbrx2 && chunk < (nchunks)) { x1 = x2; x2 += delta; bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade(bounding,wdw,outline,pattern); } } } if (poly) { if (gpgetdevice()==SCREEN) CloseShade(poly); else { FreeArrayOfBits(poly->Bordermap); FreeArrayOfBits(poly->Maskmap); free(poly); } } }