Application Development with BRL-CAD


Note: This is based on an old Power Point presentation by Lee A. Butler and John Anderson. It has been extensively reformatted and is being brought up-to-date, by the BRL-CAD Team, with the current state of the BRL-CAD source and the best practices recommended by the BRL-CAD developers

WARNING: This a code-intensive presentation for Code Warriors only! Non-programmers will need atropine, caffeine, and electro-shock therapy (run, do not walk, to the nearest exit).

The Big Six


#include "conf.h"       /* compilation macros           */
#include <stdio.h>
#include <math.h>
#include "machine.h"    /* machine specific definitions */
#include "vmath.h"      /* vector math macros           */
#include "raytrace.h"   /* librt interface definitions  */
static struct rt_i *rtip; /* librt Instance structure */
/* rt_dirbuild() performs many functions for us */
rtip = rt_dirbuild(argv[1], buf, sizeof(buf));
if (rtip == RTI_NULL) {
    fprintf(stderr,"rtexample: rt_dirbuild failure\n");
    exit(2);
}
if (rt_gettree(rtip, argv[2]) < 0)
    fprintf(stderr,"rt_gettree(%s) FAILED\n", argv[2]);

Retrieves tree top specified by argv[2] into a working set used by librt

rt_prep_parallel(rtip, 1);

Pre-computes useful terms for each primitive, e.g.,triangle normals, function roots, trig terms.

Builds space partition tree to accelerate ray-trace

struct application ap;
ap.a_rt_i = rtip;
VSET(ap.a_ray.r_pt, 0, 0, 10000);
VSET(ap.a_ray.r_dir, 0, 0, -1);
ap.a_hit = hit;	          /* where to go on a hit */
ap.a_miss = miss;         /* where to go on a miss */

(void)rt_shootray(&); /* do it */

The application struct contains information about the ray that is to be computed and what should be done with the results.

Excerpts of application struct from raytrace.h:

struct application {

    struct xray  a_ray;	/* Actual ray to be shot */
    int          (*a_hit)(struct application *,
                          struct partition *,
                          struct seg *);
    int          (*a_miss) (struct application *);
    int          a_onehit; /* flag to stop on first hit */

    struct rt_i  *a_rt_i;  /* this librt instance *
    /* ... */
};/
int
miss(register struct application *ap)
{
    bu_log("missed\n");
    return (0); /* Value returned by rt_shootray() */
}

Called when ray does not hit any geometry.

int
hit(register struct application *ap, /* see raytrace.h */
    struct partition *PartHeadp)     /* see raytrace.h */
{
    register struct partition *pp;
    register struct hit *hitp;
    point_t pt;
    for (pp = PartHeadp->pt_forw;
         pp != PartHeadp;
         pp = pp->pt_forw ) {
        hitp = pp->pt_inhit;
        VJOIN1( pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);
        VPRINT(Hit Point, pt);
    }
    return 1; /* value returned by rt_shootray();
}
int
hit(register struct application *ap,
    struct partition *PartHeadp)
{
    register struct partition *pp;
    register struct hit *hitp;
    point_t         pt;
    /* ... */
}

Partition Structure contains information about intervals of the ray which pass through geometry

Hit structure contains information about an individual boundary/ray intersection

struct partition {
    long              pt_magic;       /* sanity check               */
    struct partition *pt_forw;        /* forwards link              */
    struct partition *pt_back;        /* backwards link             */
    struct seg       *pt_inseg;       /* IN seg ptr (gives stp)     */
    struct hit       *pt_inhit;       /* IN hit pointer             */
    struct seg       *pt_outseg;      /* OUT seg pointer            */
    struct hit       *pt_outhit;      /* OUT hit ptr                */
    struct region    *pt_regionp;     /* ptr to containing region   */
    char              pt_inflip;      /* flip inhit->hit_normal     */
    char              pt_outflip;     /* flip outhit->hit_normal    */
    struct region   **pt_overlap_reg; /* NULL-terminated array of
                                       * overlapping regions.
                                       * NULL if no overlap.
                                       */
    struct bu_ptbl  pt_seglist;       /* all segs in this partition */
};

From h/raytrace.h.