LIBRT(3)
SYNOPSIS
This file seems to be out of date with the sources. Consult the headers for up-to-date information. Use the below interface documentation at your own discretion.
#include "vmath.h"
#include "raytrace.h"
extern struct rt_functab OBJ[];
extern struct rt_g rt_g;
struct rt_i *rt_dirbuild (char * mged_file_name,
char * buf,
int len);
DESCRIPTION
rt_dirbuild opens mged_file_name
and builds a directory for quick
lookup of objects. rt_dirbuild returns a pointer to a struct rt_i
on success (often called "rtip"), or RTI_NULL on failure (such as
being unable to open the named database). This pointer must be saved,
as it is a required parameter to rt_gettree
. The user-supplied
buffer buf is filled with up to len
characters of information from
the first title record in the database. If it is desired for "air"
objects to be reported as "hits" during ray-tracing, then the useair
member of the struct rt_i must be set before the first call to
rt_gettree
.
All objects (groups and regions) which are to be included in the
description to be raytraced must be preprocessed with rt_gettree
,
which returns -1 for failure and 0 for success. This function can be
called as many times as required. Be certain to pass the struct rt_i
pointer from rt_dirbuild each time.
After the last rt_gettree
call, rt_prep
can be called to complete
the preparation of internal data structures. If rt_prep
is not
explicitly called, it will be indirectly invoked by the first use of
rt_shootray
.
To fire a ray at the model, an application structure must be
prepared and its address passed to rt_shootray
. Note that it is
mandatory that you provide values for a_ray.r_pt (the starting point
of the ray to be fired), a_ray.r_dir (a unit-length direction
vector), a_hit (address of user-supplied hit routine), a_miss
(address of user-supplied miss routine), a_overlap (address of
user-supplied overlap routine; may be null), a_rt_i (struct rt_i
pointer, from rt_dirbuild), a_onehit (flag controlling stop after
first hit), a_level (recursion level, just for diagnostic printing),
and a_resource (address of resource structure; may be null).
To obtain a report of CPU usage for a portion or portions of your
program, frame the statements with calls to rt_prep_timer
and
rt_read_timer
. Each call to rt_prep_timer
resets the timing
process, after which rt_read_timer
can be called to get a double
which is the elapsed CPU time in seconds since rt_prep_timer
was
last called. In addition, up to len
bytes of system-specific
detailing of resource consumption is placed in the user-supplied
buffer buf
.
bu_bomb can be used to exit your program with msg printed on the standard error output.
WARNING
Librt is designed to run in parallel on some multiprocessor machines. On some such machines system calls must be semaphore protected.
Dynamic memory handling in applications using librt should use the functions provided by libbu instead of the usual system runtime library routines. The libbu versions do not return to the caller unless they succeed. If they fail, they call bu_bomb with their last argument (str) as the parameter. The string parameter usually indicates the purpose of the memory being allocated.
DEFINITION
RPP - Rectangular ParallelePiped. A region of space defined by minimum and maximum values in X, Y, and Z. RPPs are used by librt as bounding volumes for solids.
DISCUSSION
You should study the structures in raytrace.h, in particular, the
application structure, the partition structure and its component
structures to get an idea of what information is handed to/from
rt_shootray
. rt_shootray
may be called recursively from your
a_hit routine (good for doing bounced rays). If you only care about
the first object hit along the path of the ray, set the a_onehit
flag in the application structure before calling
rt_shootray
. rt_shootray
returns the return value of the
user-supplied hit or miss function that it called.
If the ray intersects the model, the a_hit routine is called with a
pointer to the application structure and a pointer to a linked list of
ray partitions (struct partition). Within each partition are seg
(solid segment) and hit (intersection with evaluated region)
structure pointers for the places where the ray enters and leaves this
partition of space. pt_inhit.hit_dist is the parametric distance at
which the ray enters the partition, and pt_outhit.hit_dist is the
parametric distance at which the ray leaves. Note that while the hit
structure contains hit_point and hit_norm elements, they are not
computed by rt_shootray
. If these are needed, they can be filled in
by using the RT_HIT_NORMAL macro; if surface curvature information
is needed, it can be obtained by using the RT_CURVE macro after
RT_HIT_NORMAL; if only the hit_point is needed, it can be filled
in by using the VJOIN1 macro (see the following example).
If the ray contains any overlaps (partitions claimed by two or more regions) the a_overlap routine is called for each such partition with pointers to the application structure, the overlap partition, two regions, and the remaining partitions along the ray. If the a_overlap member is null, librt uses a default overlap handler. Additionally, librt provides the routine
If the ray does not intersect the model, the a_miss routine is called with a pointer to the application structure.
Helpful in generating a grid of ray origins, the bounding RPP of the
model is computed by rt_gettree
and is stored in rtip→mdl_min and
rtip→mdl_max.
EXAMPLE
A program can be loaded as follows:
$ cc -I/usr/brlcad/include main.c /usr/brlcad/lib/librt.a -l<system-specific> -lm
where <system-specific> indicates libraries required on a particular architecture. The table below indicates which system specific libraries are necessary on a particular architecture.
Architecture |
Librarie(s) |
Alliant FX/8 |
-lcvec -lcommon |
Alliant FX/2800 |
-lcommon |
SGI 4D |
-lmpc |
Cray(X/Y) |
-L/lib/multi -lu -lio |
Cray2 |
-lmt |
Encore Multi-Max |
-lpp |
Here is a portion of a hypothetical program which uses the library:
#include <vmath.h>
#include <raytrace.h>
int
main(int argc, char argv[])
{
static int do_if_hit(), do_if_miss(); /* Application routines */
register int h, v;
int grid_sz;
struct application ap; /* Set up for rt_shootray() */
struct rt_i *rtip;
/* ... */
/* Build the directory. */
rtip = rt_dirbuild( argv[bu_optind++] );
/* Load the desired portion of the model. */
while (argv[bu_optind] != NULL)
rt_gettree(rtip, argv[bu_optind++]);
ap.a_hit = do_if_hit; /* Routine for hit */
ap.a_miss = do_if_missed; /* Routine for miss */
ap.a_overlap = 0;
ap.a_rt_i = rtip;
ap.a_level = 0;
ap.a_onehit = 0; /* Return all objects along ray */
ap.a_resource = 0;
for (v = 0; v < grid_sz; ++v) /* For each scanline */
for (h = 0; h < grid_sz; ++h) {
/* Set up ray origin. */
VMOVE( ap.a_ray.r_pt, get_grid(h, v));
/* Compute ray direction. */
VMOVE( ap.a_ray.r_dir, get_dir(h, v));
/* Must be unit vector. */
VUNITIZE(ap.a_ray.r_dir);
(void)rt_shootray(&ap);
}
/* ... */
}
static int
do_if_hit(register struct application *ap,
struct partition *PartHeadp)
{
extern void put_component();
struct curvature incurv;
register struct partition *pp;
for (pp = PartHeadp->pt_forw; pp != PartHeadp;
pp = pp->pt_forw) {
/* Fill in all inhit info, but just the exit location for outhit. */
RT_HIT_NORMAL(pp->pt_inhit->hit_normal, pp->pt_inhit,
pp->pt_inseg->seg_stp, &ap->a_ray,
pp->pt_inflip);
RT_CURVE(&incurv, pp->pt_inhit, pp->pt_inseg->seg_stp);
VJOIN1(pp->pt_outhit->hit_point, ap->a_ray.r_pt,
pp->pt_outhit->hit_dist, ap->a_ray.r_dir);
/* Do something based on information in partition structure
* such as output a shotline component data record.
*/
put_component( pp->pt_inhit, &incurv, pp->pt_outhit );
/* ... */
}
return 1; /* Report hit to main routine */
}
static int
do_if_missed(register struct application *ap)
{
return 0; /* Report miss to main routine */
}
DIAGNOSTICS
"rt_malloc: malloc failure", if librt is unable to allocate memory
with malloc. "rt_???: read error", if an error or EOF occurs while
reading from the model database. "unexpected SIGFPE!" when a floating
point error occurs. (The rootfinder traps SIGFPE, but SIGFPE elsewhere
is unexpected.) "rt_shootray: zero length dir vector" when the
a_ray.r_dir vector is not unit length. "rt_gettree called again
after rt_prep!" when an attempt is made to add more sub-trees to the
active model after calling rt_prep
(or after firing the first
ray). "rt_prep: re-invocation" when rt_prep
is called more than
once. "rt_prep: no solids to prep" when there are no valid solids in
the model.
The LIBRT_DEBUG environment variable may be set to the hexadecimal bit vector as described by the DEBUG_* flags listed in the raytrace.h header. Similarly, many LIBRT applications provide a "-x #" command-line option which will take precedence over the environment variable.
The LIBRT_V4FLIP environment variable may be set to a true or false value to respectively force or disable endianness interpretation of v4 geometry database files. The default behavior is to automatically detect whether flipping the endian interpretation will help LIBRT read a binary-incompatible v4 geometry database file. Setting LIBRT_V4FLIP will override automatic detection.
The LIBRT_BOT_MINTIE environment variable may be set to the minimum number of faces a BoT primitive must have to exercise the Triangle Intersection Engine (TIE) raytrace evaluation. A value less than or equal to zero will utilize traditional BoT raytracing instead of TIE.
BUGS
On a VAX, the rootfinder detects "hard" cases by taking a SIGFPE and retrying with a slower but more stable algorithm. This is unfortunate.
COPYRIGHT
This software is Copyright (c) 1989-2021 by the United States Government as represented by U.S. Army Research Laboratory.
BUG REPORTS
Reports of bugs or problems should be submitted via electronic mail to devs@brlcad.org