How to draw primitive shapes with BRL-CAD

How to draw primitive shapes with BRL-CAD

Primitive shapes can be used for geometric modeling of more complex shapes.

How to draw primitive shapes with BRL-CAD
Image credits : 

Isaac Kamga, CC BY

A primitive is a basic shape that has a unique polynomial equation within a CAD (Computer-Aided Design) software package used for geometric modeling of more complex shapes. Examples include an ellipse, a sphere, a torus, a square, and in our case a heart-shaped primitive with a sextic equation (a polynomial, which has six roots).

This heart-shaped primitive (a symbol of love <3) can be used by artists to produce cartoon animations, design cards, royal seals, banners, gifts, and presents for family and communal celebrations, such as weddings, family reunions, and Valentine's Day.

This article provides a guideline for the development of primitives within CAD software by highlighting the implementation of geometrically useful properties for the heart-shaped primitive within BRL-CAD, an open source CAD package developed by the U.S. Army Research Laboratory.

First, to set up an environment to develop BRL-CAD, follow these instructions.

Data structure of the heart-shaped primitive

The diagram shows the annotation of the heart shape. A magic number hrt, a center point v, vector in the direction of the X-axis xdir, vector in the directions of the Y-axis ydir, vector in the direction of the Z-axis zdir and Distance from center point to either cusps d.

Heart-shaped primitive

Tagging the heart-shaped primitive

The heart-shaped primitive is uniquely stored in BRL-CAD's database with a magic number, Ox6872743f, which is the hexadecimal equivalent of "?hrt?". We also incremented the maximum number of primitives in src/libbu/magic.c, include/magic.h, and include/raytrace.h.

After tagging the heart-shaped primitive in BRL-CAD, we went on to write callback functions, which compute geometrically useful properties. We also used a heart-shaped object called amour ( the French word for love) centered at the origin (0,0,0), possessing three radial vectors (5,0,0), (0,5,0), and (0,0,5) as well as a distance to cusps of 4. Let's suppose this object is called amour and is stored in the heart_example.g database.

Formatted description

In order to know a solid's type and the values of its key parameters, we wrote the rt_hrt_describe() function, which simply prints the heart shape's parameters in human-readable format. To describe the amour object, we print amour's parameters using BRL-CAD 's l command in both terse and verbose forms by running the l -t amour and l amour commands respectively in the archer command prompt.

Running commands from the archer command prompt

Database import and export

For the heart-shaped primitive to be used in CSG (Constructive Solid Geometry), we wrote functions that import and export data in between the database format and the internal format.

Type in support

Appropriate support for typing the parameters of the heart-shaped primitive using the keyboard into the mged or archer interfaces was then implemented. To test database import and export as well as type in support properties, we ran the BRL-CAD in amour hrt 0 0 0 5 0 0 0 5 0 0 0 5 4 command, typing in the name, primitive type (hrt), and parameters of amour into the archer command line as the picture shows.

Entering parameters of amour into the archer command line

Bounding box

The bounding box of a geometric model refers to the box with the smallest volume within which the model resides—more like the least upper bound of the set of all enclosing volumes. To compute the bounding box of the heart shape, we wrote the rt_hrt_bbox() function, which computed the minimal point (closest lower left-hand corner) and maximal point (closest lower left-hand corner) of the bounding box, respectively. To report the extent of the bounding box of the amour object, we print its minimal and maximal points by running the bb -qe amour command in either the mged or archer command prompts. Then, we ran the bb -qv amour command in archer so that the volume of the amour object is reported in cubic millimeters. After, we reported the length, width, and height of amour's bounding box by running the bb -qd amour. Finally, to report the volume and dimensions of the bounding box, we ran the bb amour command in archer's command prompt.

Running the bb amour command in archer&amp;#039;s command prompt


In order to build the wireframe of the heart-shaped primitive into BRL-CAD's functionality, we wrote the rt_hrt_plot() and rt_hrt_24pts() functions. The heart-shaped primitive's wireframe is made up of several ellipses aligned along the Z-axis, where each consists of 24 edges. As we progress in the positive Z-axis direction, we use eight ellipses (with decreasing radii) to frame the upper portions of the left and right lobes. The 24 required points for each ellipse are computed by the rt_hrt_24pts() function, which computes 24 points that are 15 apart.

Finally, the different ellipses are connected together to enrich the wireframe with more isocontours. The draw command is used to see the wireframe and -C option permits us to choose their display color. To draw the wireframe of the amour object using white wires, we ran the draw -C 255/0/0 amour command.

Amour object wireframe

Ray tracing

The heart-shaped primitive is endowed with a surface representation by ray tracing it. Ray tracing at its very core consists of solving for the intersection points of a line and a surface. Many interesting surfaces have been written as polynomial functions of the position and the heart shape is not left out. The peculiarity of our work is that we proved that ray tracing using the Laguerre-based root finder works for sextic equations (those with a degree of 6). In order to do this, we wrote rt_hrt_prep(), rt_hrt_norm(), rt_hrt_shot(), and rt_hrt_print() functions.

In order to test that the ray tracing property of the heart-shaped primitive works, we use BRL-CAD's rt command, which ray traces objects. Using the rt command, we produced 360 images each at an azimuth angle of 1 degree from the other and an elevation angle of 35 degrees from our viewpoint. The width and height of these images were 640 and 480 pixels, respectively.


for i in 'loop 000 359 1'; do

      rt -a $i -e 35 -w 640 -n 480 -o image$i.png heart_example.g amour


Here are some images of the ray traced amour object from beside, above, and below.

Raytraced amour object from besides

View of the ray-traced amour object from beside.

Raytraced amour object from above

View of the ray-traced amour object from above.

Raytraced amour object from above

View of the ray-traced amour object from below.

After appropriately sequencing these images with padded zeroes, we used the ImageMagick convert command to composite them into a single animated video showing the heart-shaped primitive spinning from beside.

This article details the technical aspects of the talk "From Africa With Love" to be presented at OSCON 2017 in Austin, Texas based on the "Implementation of a heart-shaped primitive" project the author carried out in BRL-CAD under the auspices of the Google Summer of Code program. If you're interested in attending the conference use this discount code when you register, for our readers: PCOS.

Comment now