Index of OpenRM - RM Library


 RMpsSpec * rmPSSpecNew (void)
 (No arguments)

Use this routine to create a new RMpsSpec object, which is used to specify PostScript output options to the RM renderer. Upon success, this routine returns a handle to an RMpsSpec object that has been initialized with default values (see below). Upon failure, NULL is returned.

To use the RMpsSpec object to create PostScript output, you may modify PostScript output attributes by using the appropriate routines, then provide the RMpsSpec object as input along with a scene graph and an RMpipe to the RM PostScript rendering utility, rmFramePS().

Upon creation, the new RMpsSpec object contains the following default values:

1. Page size : 612 points wide by 792 points high. These dimensions correspond to an 8.5 by 11 inch US letter document at 72 points/inch. Use the routines rmPSPageSetSize/rmPSPageGetSize to set/get the page dimensions for PS output.

2. Page orientation: RM_PS_PORTAIT. The document uses a default orientation of portrait. Use the routines rmPSPageSetOrientation/rmPSPageGetOrientation to set/get the page orientation.

3. Margin: The minimum margin is 36 points (0.5 inches). Use the routines rmPSPageSetMargin/rmPSPageGetMargin to set/get the margin.

4. PS Format: The default PostScript output format is RM_PS_REGULAR, or regular PostScript output (the alternative would be RM_PS_EPS for Encapsulated PostScript). Use the routines rmPSPageSetOutputFormat/ rmPSPageGetOutputFormat to set/get the PostScript output format.

5. Vector output format: The default vector output form is RM_PS_VECTOR (the alternative is RM_PS_RASTER). Use the routines rmPSPageSetVectorFormat/ rmPSPageGetVectorFormat to set/get the output vector format.

6. Sorting method: The default sorting method used to convert from 3D scenes to ordered 2D PostScript primitives is RM_PS_SORT_FULL. Use the routines rmPSSetSortMethod/rmPSGetSortMethod to set/get the sort attributes.

7. Output filename: The default output filename is "rmPSFile.ps". Use the routines rmPSSetOutputFilename/rmPSGetOutputFilename to set/get the file name where PostScript output will be placed.

Note: you could malloc() your own RMpsSpec object, or use one declared off the heap if you so desire. The advantage of using rmPSSpecNew() is that the new RMpsSpec object will be initialized to a set of known default values.

librm library source file: rmps.c

 RMenum rmPSSpecDelete (RMpsSpec *toDelete)
 RMpsSpec *toDelete - an handle to an RMpsSpec object that will be deleted.

Use this routine to delete an RMpsSpec object created by rmPSSpecNew. Upon success, RM_CHILL is returned and the RMpsSpec object toDelete is deleted. Upon failure, RM_WHACKED is returned and the object toDelete is not deleted.

librm library source file: rmps.c

 RMenum rmPSPageSetSize (RMpsSpec *toModify, int pagePointsWidth, int pagePointsHeight)
 RMpsSpec *toModify - an handle to an RMpsSpec object that will be modified.
 int pagePointsWidth, pagePointsHeight - the width and height in points of the
    output PostScript document.

This routine will set the output page size dimensions in points of the output PostScript image. Upon success, RM_CHILL is returned and the RMpsSpec object toModify will be updated to contain the new size attributes specified by the caller. Upon failure, RM_WHACKED is returned and the RMpsSpec object toModify is left unmodified.

librm library source file: rmps.c

 RMenum rmPSPageGetSize (const RMpsSpec *toQuery, int *returnPagePointsWidth, int *returnPagePointsHeight)
 const RMpsSpec *toModify - an handle to an RMpsSpec object that will be queried.
 int *returnPagePointsWidth, *returnPagePointsHeight - pointers to caller-
   supplied memory where results will be placed.

Use this routine to query the PostScript page size dimensions. Upon success, RM_CHILL is returned, and the page size width and height (in points) will be copied into caller-supplied memory. Upon failure, RM_WHACKED is returned and the caller-supplied memory will remain unchanged.

Note that you may use a value of NULL for either of returnPagePointsWidth or returnPagePointsHeight if you wish to obtain only one, both or none of the page size attributes.

librm library source file: rmps.c

 RMenum rmPSPageSetOrientation (RMpsSpec *toModify, RMenum orientation)
 RMpsSpec *toModify - an handle to an RMpsSpec object that will be modified.
 RMenum orientation - an enumerator value that specifies the orientation for
   the PostScript output. Must be one of RM_PS_PORTRAIT or RM_PS_LANDSCAPE.

Use this routine to specify the page orientation for PostScript output. When you specify RM_PS_PORTRAIT, the imageable area is oriented such that the width axis of the output PostScript is oriented along the width axis of the output page. When you specify RM_PS_LANDSCAPE, the width axis of the output PostScript is oriented along the height axis of the output page.

Upon success, this routine returns RM_CHILL and updates the RMpsSpec object toModify. Upon failure, which can occur of the RMpsSpec object is NULL or if the input orientation enumerator is neither RM_PS_PORTRAIT nor RM_PS_LANDSCAPE, RM_WHACKED is returned and the RMpsSpec object is not modified.

librm library source file: rmps.c

 RMenum rmPSPageGetOrientation (const RMpsSpec *toQuery)
 const RMpsSpec *toQuery - an handle to an RMpsSpec object that will be queried.

Use this routine to query the page orientation attribute of an RMpsSpec object. Upon failure, RM_WHACKED is returned. Upon success, the page orientation attribute is returned (RM_PS_LANDSCAPE or RM_PS_PORTRAIT).

librm library source file: rmps.c

 RMenum rmPSPageSetOutputFormat (RMpsSpec *toModify, RMenum newFormat)
 RMpsSpec *toModify - an RM object holding PostScript generation options.
 RMenum newFormat - a format enumerator for the type of PS to output. Must
    be one of RM_PS_REGULAR or RM_PS_EPS.

There are many parameters that affect how RM produces PostScript output from a scene graph. These parameters are all specified to RM via an RMpsSpec object. See rmPSSpecNew() for information about creating RMpsSpec objects, and see the RM Programming Guide for complete information about all the PostScript output attributes.

Use this routine to specify whether the PostScript output file will be "normal" PostScript (RM_PS_REGULAR) or Encapsulated PostScript (RM_PS_EPS).

Returns RM_CHILL upon success. RM_WHACKED is returned if the toModify parameter is NULL, or if newFormat is not one of RM_PS_REGULAR or RM_PS_EPS.

librm library source file: rmps.c

 RMenum rmPSPageGetOutputFormat (const RMpsSpec *toQuery)
 const RMpsSpec *toQuery - an RM object holding PostScript generation options.

Use this routine to obtain the PostScript output format specifier. Upon success, on of RM_PS_REGULAR or RM_PS_EPS will be returned. Upon failure, RM_WHACKED will be returned.

librm library source file: rmps.c

 RMenum rmPSPageSetVectorFormat (RMpsSpec *toModify, RMenum newFormat)
 RMpsSpec *toModify - an RM object holding PostScript generation options.
 RMenum newFormat - input enumerator that must be either RM_PS_VECTOR or
    RM_PS_RASTER.

Use this routine to select between vector (RM_PS_VECTOR) or raster (RM_PS_RASTER) PostScript formats. Upon success, RM_CHILL is returned and the new PostScript output will be applied to the RMpsSpec object toModify. Upon failure, RM_WHACKED will be returned, and the RMpsSpec object toModify will not be modified. Failure will occur if the input RMpsSpec object toModify is NULL, or if the input RMenum newFormat is neither RM_PS_VECTOR nor RM_PS_RASTER.

librm library source file: rmps.c

 RMenum rmPSPageGetVectorFormat (const RMpsSpec *toQuery)
 const RMpsSpec *toQuery - an RM object holding PostScript generation options.

Use this routine to obtain the raster vs. vector PostScript output format attribute from an RMpsSpec object. Upon success, one of RM_PS_RASTER or RM_PS_VECTOR will be returned. Upon failure, RM_WHACKED is returned.

librm library source file: rmps.c

 RMenum rmPSPageSetMargin (RMpsSpec *toModify, int minMarginPoints)
 RMpsSpec *toModify - an handle to an RMpsSpec object that will be modified.
 int minMarginPoints - an integer value specifing the minimum margin size
    in units of points (one point = 1/72 of an inch).

Use this routine to set the minimum margin (in points) attribute of the RMpsSpec object toModify. Upon success, RM_CHILL is returned and the RMpsSpec object toModify is updated. Upon failure, RM_WHACKED is returned.

The term "minimum margin" means that a single margin value is used to specify minimum margin sizes that will be used when computing the mapping to the printable page. Under normal circumstances, the rendered image is automatically sized to fill the full PS output page. The margin attribute controls how much whitespace remains at the border of the page.

For example, if you specify a 0.5inch minimum margin (36 points) on an A4 output page (8.5inches by 11 inches), portrait orientation and your on-screen window is 400 by 300 pixels, the imageable area will fill the page width except for 0.5 inches of margin at each of the left and right sides. The top and bottom margin will be much larger, however, due to the fact that you are mapping the larger imageable area size to the smaller page dimension.

librm library source file: rmps.c

 RMenum rmPSPageGetMargin (const RMpsSpec *toModify, int *marginPointsReturn)
 const RMpsSpec *toQuery - an handle to an RMpsSpec object that will be
   queried.
 int * marginPointsReturn - a handle to a caller-supplied integer. The
   margin size attribute of the input RMpsSpec object will be copied into
   caller-supplied memory. 

Use this routine to obtain the minimum margin attribute from an RMpsSpec object. Upon success, RM_CHILL is returned and the margin attribute value is copied into caller-supplied memory. Upon failure, RM_WHACKED is returned and the caller-supplied memory remains unmodified.

Note that it is permissible to specify a value of NULL for the caller-supplied memory.

librm library source file: rmps.c

 RMenum rmPSSetOutputFilename (RMpsSpec *toModify, const char *fileName)
 RMpsSpec *toModify - an handle to an RMpsSpec object that will be modified.
 const char *fileName - a character string (input).

Use this routine to set the name of the file to which PostScript output will be placed when you call rmFramePS() to render a scene to PostScript. Upon success, this routine will return RM_CHILL, and the input filename will be copied into the RMpsSpec object toModify. Upon failure, RM_WHACKED is returned and the RMpsSpec object toModify will remain unmodified.

librm library source file: rmps.c

 const char * rmPSGetOutputFilename (const RMpsSpec *toQuery)
 const RMpsSpec *toQuery - an handle to an RMpsSpec object to query.

Use this routine to obtain read-only access to the filename from an RMpsSpec object where PostScript output will be written. Upon failure, NULL is returned. Upon success, a read-only character string is returned.

librm library source file: rmps.c

 RMenum rmPSSetSortMethod (RMpsSpec *toModify, RMenum sortMethod)
 RMpsSpec *toModify - an RM object holding PostScript generation options.
 RMenum sortMethod - an enumerator that specifies which sorting method
   will be used when creating the PS file.

There are many parameters that affect how RM produces PostScript output from a scene graph. These parameters are all specified to RM via an RMpsSpec object. See rmPSSpecNew() for information about creating RMpsSpec objects, and see the RM Programming Guide for complete information about all the PostScript output attributes.

In generating PostScript output, RM needs to sort primitives in back-to-front order since PS has no notion of a depth buffer. Sorting primitives is an expensive, time-consuming operation. RM provides four methods you can use for generating PostScript files:

RM_PS_SORT_FAST - will make a single pass through the primitives and sort them in back-to-front order using the primitive's centroid. This method uses qsort internally, and as such is an O(N logN) operation. If the primitives in the scene don't have much overlap in either x/y space or in depth, then this method should produce satisfactory results.

RM_PS_SORT_FULL - this method will perform full geometric sorting of all primitives in the scene using a Binary Space Partition algorithm. The RM_PS_SORT_FULL algorithm is of O (N logN) complexity, and as such will run in comparable run time to RM_PS_SORT_FAST, depending upon scene complexity. In all instances, it has greater memory requirements than RM_PS_SORT_FAST. In some cases, the memory requirements can be substantial.

RM_PS_SORT_HYBRID_SCREEN_BSP - this sorting algorithm uses a novel hybrid method of partitioning: it will first subdivide the primitives into screen-space tiles. Primitives that cross tile boundaries are subdivided so that the resulting primitive fragments are entirely contained within a screen space tile. When the number of primitives within that screen tile falls below a certain threshold (a constant in the code) or if the tile area falls below a certain threshold (also a constand in the code), then the primitives contained within that screen are then sorted using RM_PS_SORT_FULL. This approach has the benefit of reducing algorithmic complexity, which in turn results in much faster run times than RM_PS_SORT_FULL as well as reduced memory requirements. Note, however, that RM_PS_SORT_HYBRID_SCREEN_BSP will result in PS rendering artifacts if you specify "fat" line drawing styles or point sizes greater than one pixel. This sorting technique is interesting, but should be viewed as experimental.

RM_PS_SORT_HYBRID_DEPTH_BSP - another hybrid approach to reduce run time and memory requirements as compared to a full BSP sort. This algorithm will first subdivide the scene using planes positioned in depth (rather than screen tiles). While this approach is not quite as fast or memory effecient as RM_PS_SORT_HYBRID_SCREEN_BSP, it does not exhibit any of the rendering errors, and its memory and runtime performance are substantially better than RM_PS_SORT_FULL.

When you create an RMpsSpec object with rmPSSpecNew(), the default sorting method assigned to the RMpsSpec object is RM_PS_SORT_FULL.

Returns RM_CHILL upon success. RM_WHACKED is returned if the toModify parameter is NULL, or if newFormat is not one of RM_PS_REGULAR or RM_PS_EPS.

librm library source file: rmps.c

 RMenum rmPSGetSortMethod (const RMpsSpec *toQuery)
 const RMpsSpec *toQuery - an RMpsSpec object that will be queried.

Use this routine to query the sort method specification from an RMpsSpec object. Upon failure, RM_WHACKED is returned. Upon success, the sorting method is returned to the caller (RM_PS_SORT_FULL, RM_PS_SORT_FAST, RM_PS_SORT_HYBRID_SCREEN_BSP, RM_PS_SORT_HYBRID_DEPTH_BSP).

librm library source file: rmps.c

 RMenum rmFramePS (RMpipe *drawOn, RMnode *subTree, RMpsSpec *spec)
 RMpipe *drawOn - the RMpipe environment used to draw the scene.
 RMnode *subTree - the scene.
 RMpsSpec *spec - an RMpsSpec containing PS parameter specifications.

rmFramePS is used to render a scene into a PostScript[tm] file. The final rendered frame contents are a function of the (1) relevant parameters specified in the input RMpipe "drawOn" (like display window pixel dimensions, etc.); (2) the scene contents as specified by the scene graph rooted at the RMnode "subTree"; (3) PS-specific parameters and algorithmic controls specified via the RMpsSpec parameter.

See rmPSSpecNew() for an introduction to the numerous parameters provided for specifying PS rendering algorithmic control and output options.

Upon success, RM_CHILL is returned; upon failure, RM_WHACKED is returned.

librm library source file: rmps.c

 RMenum rmFramePSHeartbeat(RMpipe *drawOn, RMnode *subTree, RMpsSpec *p, int (*heartBeatFunc)(int percentComplete))
 RMpipe *drawOn - the RMpipe environment used to draw the scene.
 RMnode *subTree - the scene.
 RMpsSpec *spec - an RMpsSpec containing PS parameter specifications.
 int (*heartBeatFunc)(int percentComplete) - an application supplied callback function.

rmFramePSHeartbeat is identical to function and behavior to rmFramePS with one exception - it will accept as input an application-provided callback (the "heartbeat function"). The callback will be periodically invoked during the PS generation process. When invoked:

1. The application can "interrupt" and prematurely abort the PS generation process by having the heartbeat callback function return a non-zero value to RM. In other words, if the heartbeat application callback returns a value of zero to RM, PS output processing will continue; if the application heartbeat application callback returns a non-zero value, PS output processing will terminate. Control will be returned to the application, and the return status (RM_CHILL or RM_WHACKED) does not indicate whether or not processing was prematurely aborted due to a non-zero return status from the application heartbeat callback.

2. The application will be provided an estimate of "percent complete" via the integer parameter "percentComplete." A value of zero means the algorithm has not yet begun; a value of one hundred (100) means the algorithm has completed. See Note D below for more information about the meaning of this parameter during lengthy sorting operations.

Notes:

A. During raster postscript output processing, the heartbeat function is invoked at 0, 50, and 100 percent complete. Its return status is ignored, which means that the application cannot interrupt PS output when the RM_PS_RASTER output format is requested. The reasoning is that only lengthy sorting operations should be interruptable via the heartbeat callback.

B. During vector postscript output processing, the heartbeat function is invoked at a mixture of "hard coded" percent complete points that correspond to algorithmic milestones, and the return status from the heartbeat application callback is ignored at those points.

C. While lengthy sort operations are conducted during vector PS processing, the heartbeat callback is periodically invoked. "Periodically" means approximately once per second. The sorting operation may be interrupted by the application vis-a-via returning a non-zero value from the heartbeat callback function.

D. A best-effort algorithm is used to report an accurate percent-complete value via the integer parameter to the heartbeat callback. However, due to the nature of how the PS sorting operation works, the percent complete value is not guaranteed to be monotonic or accurate. We have found it to be both monotonic and reasonably accurate in all cases we have tested. Since the underlying method used to compute "percent complete" takes into account the number of remaining unsorted primitives; this number can increase depending upon the scene complexity and partition planes used during binary space partitioning.

librm library source file: rmps.c