/* surface-trimmed.c 1.1 */ /* Copyright 1992, 1993 O'Reilly and Associates, Inc. Permission to use, copy, and modify this program is hereby granted, as long as this copyright notice appears in each copy of the program source code. */ #include "book_utils.h" /* The surface knots and control points. */ static float uknots[] = { 0, 0, 0, 1, 1, 1 }; static float vknots[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; static PEXCoord control_points[] = { {0.0, 0.5, 0.0}, {0.0, 0.6, 0.5}, {0.0, 0.5, 1.0}, {0.3, 0.5, 0.0}, {0.3, 1.0, 0.5}, {0.3, 0.5, 1.0}, {0.6, 0.4, 0.0}, {0.6, 0.5, 0.5}, {0.6, 0.4, 1.0}, {0.9, 0.5, 0.0}, {0.9, 0.3, 0.5}, {0.9, 0.2, 1.0}}; /* Trimming Curves, from inner-most to outer-most. */ static float t0_knots[] = {0,0,0,1,1,2,2,3,3,4,4,4 }; static PEXCoord2D t0_pts[] = { {0.5,0.32},{0.68,0.32},{0.68,0.5},{0.68,0.68},{0.5,0.68}, {0.32,0.68},{0.32,0.5},{0.32,0.32},{0.5,0.32}}; static float t1_knots[] = {0,0,0,1,1,2,2,3,3,4,4,4 }; static PEXCoord2D t1_pts[] = { {0.5,0.25},{0.25,0.25},{0.25,0.5}, {0.25,0.75},{0.5,0.75}, {0.75,0.75},{0.75,0.5},{0.75,0.25},{0.5,0.25}}; static float t2_knots[] = { 0, 0, 1, 2, 3, 4, 4 }; static PEXCoord2D t2_pts[] = {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}; static void redraw( dpy, window, renderer ) Display *dpy; Window window; PEXRenderer renderer; { int uorder = 3, vorder = 4; unsigned int num_u_points = 3, num_v_points = 4; PEXArrayOfCoord grid; PEXColor color; PEXPSCData psc; unsigned long num_trim_loops; PEXListOfTrimCurve trim_loops[3]; PEXTrimCurve trim_curves[3]; XClearWindow( dpy, window ); PEXBeginRendering( dpy, window, renderer ); { /* Use the view defined by set_view(). */ PEXSetViewIndex( dpy, renderer, PEXOCRender, 1 ); /* Set the interior style. */ PEXSetInteriorStyle( dpy, renderer, PEXOCRender, PEXInteriorStyleEmpty ); /* Set the color of the isoparametric curves. */ SET_COLOR( 1, 1, 1, color ); PEXSetLineColor( dpy, renderer, PEXOCRender, PEXColorTypeRGB, &color ); /* Set the parametric surface characteristics. */ psc.iso_curves.placement_type = PEXUniformPlacement; psc.iso_curves.u_count = 20; psc.iso_curves.v_count = 20; PEXSetParaSurfCharacteristics( dpy, renderer, PEXOCRender, PEXPSCIsoCurves, &psc ); /* Set the surface approximation criteria. */ PEXSetSurfaceApprox( dpy, renderer, PEXOCRender, PEXApproxConstantBetweenKnots, (double)10, (double)10 ); /* Build the trimming loops. Here, each loop is a single */ /* curve. */ num_trim_loops = 3; trim_loops[0].count = 1; trim_loops[0].curves = &trim_curves[0]; trim_loops[1].count = 1; trim_loops[1].curves = &trim_curves[1]; trim_loops[2].count = 1; trim_loops[2].curves = &trim_curves[2]; trim_curves[0].rationality = PEXNonRational; trim_curves[0].visibility = PEXOn; trim_curves[0].order = 3; trim_curves[0].tmin = 0; trim_curves[0].tmax = 4; trim_curves[0].knots.count = sizeof(t0_knots)/sizeof(t0_knots[0]); trim_curves[0].knots.floats = t0_knots; trim_curves[0].count = sizeof(t0_pts)/sizeof(t0_pts[0]); trim_curves[0].control_points.point_2d = t0_pts; trim_curves[0].approx_method = PEXApproxConstantBetweenKnots; trim_curves[0].tolerance = 10; trim_curves[1].rationality = PEXNonRational; trim_curves[1].visibility = PEXOn; trim_curves[1].order = 3; trim_curves[1].tmin = 0; trim_curves[1].tmax = 4; trim_curves[1].knots.count = sizeof(t1_knots)/sizeof(t1_knots[0]); trim_curves[1].knots.floats = t1_knots; trim_curves[1].count = sizeof(t1_pts)/sizeof(t1_pts[0]); trim_curves[1].control_points.point_2d = t1_pts; trim_curves[1].approx_method = PEXApproxConstantBetweenKnots; trim_curves[1].tolerance = 10; trim_curves[2].rationality = PEXNonRational; trim_curves[2].visibility = PEXOn; trim_curves[2].order = 2; trim_curves[2].tmin = 0; trim_curves[2].tmax = 4; trim_curves[2].knots.count = sizeof(t2_knots)/sizeof(t2_knots[0]); trim_curves[2].knots.floats = t2_knots; trim_curves[2].count = sizeof(t2_pts)/sizeof(t2_pts[0]); trim_curves[2].control_points.point_2d = t2_pts; trim_curves[2].approx_method = PEXApproxConstantBetweenKnots; trim_curves[2].tolerance = 10; /* Create the surface. */ grid.point = control_points; PEXNURBSurface( dpy, renderer, PEXOCRender, PEXNonRational, uorder, vorder, uknots, vknots, num_u_points, num_v_points, grid, num_trim_loops, trim_loops ); } PEXEndRendering( dpy, renderer, True ); XFlush( dpy ); } static void set_view( dpy, view_table ) Display *dpy; PEXLookupTable view_table; { PEXViewEntry view; PEXCoord2D window[2]; double view_plane, front_plane, back_plane; PEXCoord prp; PEXNPCSubVolume viewport; /* The view orientation parameters. */ static PEXCoord view_ref_pt = {0.5, 0.5, 0.5}; static PEXVector view_plane_normal = {0.5643, 0.4775, 0.6735}; static PEXVector view_up_vec = {0,1,0}; /* Compute the view orientation transform. */ PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal, &view_up_vec, view.orientation ); /* The view mapping parameters. */ prp.x = 0; prp.y = 0; prp.z = 10; window[0].x = -0.78; window[1].x = 0.7; window[0].y = -0.78; window[1].y = 0.7; front_plane = 1; view_plane = 0; back_plane = -1; viewport.min.x = 0; viewport.max.x = 1; viewport.min.y = 0; viewport.max.y = 1; viewport.min.z = 0; viewport.max.z = 1; /* Compute the view mapping transform. */ PEXViewMappingMatrix( window, &viewport, False, &prp, view_plane, back_plane, front_plane, view.mapping ); /* The view clipping parameters. */ view.clip_flags = PEXClippingAll; view.clip_limits = viewport; /* Set view 1. */ PEXSetTableEntries( dpy, view_table, 1, 1, PEXLUTView, (PEXPointer) &view ); } #define WIN_GEOM "500x500+50+50" main( argc, argv ) int argc; char *argv[]; { Display *dpy; Window window; XEvent event; XVisualInfo vis_info; XColor bkgd_color; XStandardColormap cmap_info; PEXColorApproxEntry capx_info; PEXRenderer renderer; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; int done = 0; /* Open a display and initialize PEX. */ dpy = ora_init_pex( argv, &pexinfo ); if ( !dpy ) exit(1); /* Determine the best visual to use. */ ora_find_best_visual( dpy, &vis_info ); /* Get a standard colormap for the visual. */ if ( !ora_get_standard_colormap( dpy, &vis_info, &cmap_info ) ) { fprintf ( stderr, "Cannot find a standard colormap\n" ); exit(1); } ora_set_stdcmap_approx( &vis_info, &cmap_info, &capx_info ); /* Create the window, giving it a gray background. */ bkgd_color.red = bkgd_color.green = bkgd_color.blue = 0x5555; bkgd_color.flags = DoRed | DoGreen | DoBlue; window = ora_create_window( dpy, &vis_info, &cmap_info, WIN_GEOM, &bkgd_color ); if ( IMMED_MODE_SPT( pexinfo ) ) { renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "No immediate mode.\n" ); exit(1); } /* Set the view. */ set_view( dpy, rattrs.view_table ); /* Read and respond to X events. */ XSelectInput( dpy, window, ExposureMask | ButtonPressMask ); while ( !done ) { XNextEvent( dpy, &event ); switch ( event.type ) { case Expose: /* Flush remaining Expose events, then redraw. */ while ( XCheckTypedWindowEvent( dpy, window, Expose, &event ) ) ; /* empty statement */ redraw( dpy, window, renderer ); break; case ButtonPress: done = 1; break; } } XCloseDisplay( dpy ); return 0; }