The Hacker's Guide to BRL-CAD
=============================

Please read this document if you are contributing to BRL-CAD.

BRL-CAD is a relatively large package with a long history and
heritage.  Many people have contributed over the years, and there
continues to be room for involvement and improvement in just about
every aspect of the package.  As such, contributions to BRL-CAD are
very welcome and appreciated.

For the sake of code consistency and long-term evolution of BRL-CAD,
there are guidelines for getting involved.  Developers are strongly
encouraged to follow these guidelines.  There are simply too many
religious wars over what usually come down to personal preferences and
familiarity that are distractions from making productive progress.

Although BRL-CAD was originally developed and supported primarily by
the U.S. Army Research Laboratory and its affiliates, it is now a
true Open Source project with source code contributions coming from
around the world.  The U.S. Army Research Laboratory continues to
support and contribute to BRL-CAD, but now the source code is
primarily driven by a team of core developers and the BRL-CAD open
source community.  Contact the BRL-CAD developers for more
information.


TABLE OF CONTENTS
-----------------
  Introduction
  Table of Contents
  Getting Started
  How to Contribute
  Source Code Languages
  Filesystem Organization
  Coding Style
  Documentation
  Testing
  Patch Submission Guidelines
  Bugs
  Commit Access
  Version Numbers & Compatibility
  Making a Release
  Getting Help


GETTING STARTED
---------------

As there are many ways to get started with BRL-CAD, one of the most
important steps for new developers to do is get involved in the
discussions and communicate with the BRL-CAD developers.  There are
mailing lists, on-line forums, and an IRC channel dedicated to BRL-CAD
developer communication.  Developers are encouraged to participate in
all of them.

* E-mail Mailing Lists

  Go to http://sourceforge.net/mail/?group_id=105292 and join the
  "brlcad-devel" mailing list.  More involved developers will also
  want to join the "brlcad-commits" and "brlcad-tracker" lists.

* On-line Forums

  Discussion forums are available on the project site at
  http://sourceforge.net/forum/?group_id=105292 for both developers
  and users.  Of particular interest to developers is, of course, the
  "Developers" forum.

* Internet Relay Chat

  The primary and generally preferred mechanism for interactive
  developer discussions is via IRC.  Several of the core developers
  and users of BRL-CAD hang out in #brlcad on the Freenode network.
  With most any IRC client you should be able to join #brlcad on
  irc.freenode.net, port 6667.  See http://freenode.net and
  http://irchelp.org for more information

To contribute source code to BRL-CAD, begin by submitting source code
patches to the patches section at http://sf.net/projects/brlcad/.
Patches in the universal diff format (diff -u) are preferred.


HOW TO CONTRIBUTE
-----------------

BRL-CAD's open source developer management structure is best described
as a meritocracy.  Roughly stated, this basically means that the power
to make decisions lies directly with the individuals that have ability
or merit with respect to BRL-CAD.  An individual's ability and merit
is basically a function of their past and present contributions to the
project.  Those who constructively contribute and are involved have
more say than those who don't.

As BRL-CAD is comprised of a rather large code base, there are many
many places where one may begin to get involved.  More than likely,
there is some new goal you already have in mind, be it a new geometry
converter, support for a different image type, a fix to some bug, or
something else entirely.  Regardless of the goal or contribution, it's
highly encouraged that you interact with the developers and discuss
your intentions if you would like to see your modification added to
BRL-CAD.  When in doubt, working on resolving existing bugs, improving
performance, documentation, and writing tests are perfect places to
begin.

For many, at first, it can be overwhelming at just how much there is.
To a certain extent, you will need to familiarize yourself with the
basic existing facilities before adding a completely new feature.
There is documentation available at in the source distribution's doc/
directory, throughout the source hierarchy in manpages, and at
http://sourceforge.net/docman/?group_id=105292 covering a variety of
topics.

It is not uncommon that some particular piece of code that you are
either working on or thinking about writing is in fact already
written.  Again, working with the other developers and reading the
source code itself is a great place to begin.


SYSTEM ARCHITECTURE
-------------------

At a glance, BRL-CAD consists of about a dozen libraries and over 400
executable binaries.  The package has been designed from the ground up
adopting a UNIX methodology, providing many tools that may often be
used in harmony in order to complete a task at hand.  These tools
include geometry and image converters, image and signal processing
tools, various raytrace applications, and geometry manipulators.

One of the firm designs of the architecture is to be as cross-platform
as is realistically possible.  As such, BRL-CAD maintains support for
many very old systems and devices for as long as it is reasonably
possible (and as long as there are resources to maintain such
support).

In correlation with a long-standing heritage of support is a design
intent to maintain verifiable repeatable results throughout the
package, in particular in the raytrace library.  BRL-CAD includes
scripts that will compare a given compilation against the performance
of one of the very first systems to support BRL-CAD: a VAX 11/780
running BSD.  As the benchmark is a metric of the raytrace application
itself, the performance results are a very good metric for weighing
the relative computational strength of a given platform.  The
mathematically intensive computations exercise the CPU, system memory,
various levels of data and instruction cache, the operating system,
and compiler optimization capabilities.

To support what has evolved to be a relatively large software package,
there are a variety of support libraries and interfaces that have
aided to encapsulate and simplify application programming.  At the
heart of BRL-CAD is a Constructive Solid Geometry (CSG) raytrace
library.  BRL-CAD has its own database format for storing geometry to
disk which includes both binary and text file format representations.
The raytrace library utilizes a suite of other libraries that provide
other basic application functionality.

The Libraries

librt: The Ray-Trace library is a performance and accuracy-oriented
ray intersection library that supports a wide variety of primitive
geometry types.  Geometry can be grouped into combinations and regions
using CSG boolean operations.

libbu: The BRL-CAD Utility library contains a wide variety of routines
for memory allocation, threading, string handling, argument support,
linked lists, and more.

libbn: The BRL-CAD Numerics library provides many floating-point math
manipulation routines for vector and matrix math, a polynomial
equation solver, noise functions, random number generators, complex
number support, and more as well.

libcursor: The cursor library is a lightweight cursor manipulation
library similar to curses but with less overhead.

libdm: The display manager library contains the logic for generalizing
a drawable context.  This includes the ability to output
drawing/plotting instructions to a variety of devices such as X11,
Postscript, OpenGL, plot files, textfiles, and more.  There is
generally structured order to data going to a display manager (like
the wireframe in the geometry editor).

libfb: The framebuffer library is an interface for managing a graphics
context that consists of pixel data.  This library supports multiple
devices directly, providing a generic device-independent method of
using a frame buffer or files containing frame buffer images.

libfft: The Fast-Fourier Transform library is a signal processing
library for performing FFTs or inverse FFTs efficiently.

libmultispectral: The multispectral optics library is a separate
compilation mode of the raytrace library where support for additional
bands of energy is added.  By providing a defined spectrum of energy,
the raytrace library will produce different signal analyses for a given
set of geometry.

liboptical: The optical library is the basis for BRL-CAD's shaders.
This includes shaders such as the Phong and Cook-Torrence lighting
models, as well as various visual effects such as texturing, marble,
wood graining, air, gravel, grass, clouds, fire, and more.

liborle: The "old" run-length encoding library that will decode and
encode University of Utah Raster Toolkit format Run-Length Encoded
data.

libpkg: The "Package" library is a network communications library that
supports multiplexing and demultiplexing synchronous and asynchronous
messages across stream connections.  The library supports a
client-server communication model.

librtserver: The ray-trace server library is a thin interface over
librt that simplifies the process of applying individual ray
intersection tests against a given set of geometry.  The library
supports communication with a BRL-CAD geometry repository and
multithreaded ray dispatch.

libsysv: The System 5 compatibility library exists to support dated
systems that lack functionality required by BRL-CAD.  This library is
deprecated and should not be used for new development.

libtclcad: The Tcl-CAD library is a thin interface that assists in the
binding of an image to a Tk graphics context.

libtermio: The terminal I/O library is a TTY control library for
managing a terminal interface.

libwdb: The "write database" library provides a simple interface for
the generation of BRL-CAD geometry files supporting a majority of the
various primitives available as well as combination/region support.
The library is a write-only interface (librt is necessary to read &
write) and is useful for procedural geometry.


SOURCE CODE LANGUAGES
---------------------

The vast majority of BRL-CAD is written in C.  A majority of the MGED
geometry editor is written in a combination of C, Tcl/Tk, and Incr
Tcl/Tk.  The BRL-CAD Benchmark, build system, and utility scripts are
written in Bourne Shell Script.  An initial implementation of a
BRL-CAD Geometry Server is written in PHP.

With release 7.0, BRL-CAD has moved forward and worked toward making
all of BRL-CAD C code conform with the ANSI/ISO standard for C
language compilation (ISO/IEC 9899:1990).  Support for older compilers
and older K&R-based system facilities is being migrated to the build
system declarations and preprocessor defines.


FILESYSTEM ORGANIZATION
-----------------------

Here is a sample (not comprehensive) of how some of the sources are
organized in the source distribution:

bench/
	The BRL-CAD Benchmark Suite
db/
	Example geometry databases
doc/
	Documentation
include/
	Public headers
m4/
	Compilation resource files
misc/
	Anything not categorized or sufficently en masse
pix/
	Sample raytrace images
regress/
	Test suite
sh/
	Utility scripts
src/
	Sources
src/anim/
	Animation utilities
src/conv/
	Geometry converters (most, but not all)
src/conv/iges/
	IGES converter
src/fb/
	Framebuffer services
src/fbserv/
	Framebuffer server
src/java/
	Java raytrace interface to librt
src/lib*
	BRL-CAD libraries
src/libbn/
	Basic numerics library
src/libbu
	Basic utility library
src/libfb/
	Framebuffer library
src/libfft/
	Fast Fourier transform library
src/libpkg/
	Network "package" library
src/librt
	Raytrace library
src/libwdb/
	Write-only database library
src/mged/
	Geometry editor
src/other/
	External frameworks (Tcl/Tk, libpng, zlib, etc)
src/proc-db/
	Procedural geometry generators
src/remrt/
	Distributed raytrace support
src/rt/
	Raytracers
src/util/
	Various data processing utilities


CODING STYLE
------------

For anyone who plans on contributing code, the following conventions
should be followed.  Contributions that do not conform are likely to
be ridiculed and rejected until they do.

Code Organization:

Code that is potentially useful to another application, or that may be
abstracted in such a way that it is useful to other applications,
should be put in a library and not in application directories.

Header files private to a library go into that library's directory.
Public header files go intp the include/ directory on the top level.
Public header files should not include any headers that are private.

C files use the .c extension.  Header files use the .h extension.

GNU Build System:

The GNU Autotools build system (e.g. autoconf defines) should be used
extensively to test for availability of system services such as
standard header files, available libraries, and data types.  No
assumptions should be made regarding the availability of any
particular header, function, datatype, or other resource.  After
running the configure script, there will be an autogenerated
include/brlcad_config.h file that contains many preprocessor
directives and type declarations that may be used where needed.

Generic platform checks (e.g. #ifdef unix, #ifdef _WIN32) are highly
discouraged and should not be used.  Replace those checks with tests
for the actual facility being utilized instead.

The Windows platform utilizes its own manually-generated configure
results header (include/config_win.h) that has to be manually updated
if new tests are added to the configure.ac template.

The BRL-CAD sources as well as packages linking to BRL-CAD should
include the common.h header.  They should not include brlcad_config.h
or config_win.h directly.  The common.h header should be listed before
any other headers.

Coding Standards:

Features of C that conform to the ISO/IEC 9899-1990 C standard (C90)
are generally the baseline for strict language conformance.
Particulars of the usage of the language calls special attention to
the following:

Globals variables, structures, and other data types are discouraged -
globals are often the easy way around a hard coding problem, try to
find another solution unless there is a good reason.

"//" style comments are not allowed.  This is mainly to cause less
grief when porting to the older systems where such support is
frequently not available.

Code Formatting Conventions:

The code should strive to achieve conformance with the GNU coding
standard with a few exceptions, omissions, and reminders listed below.
The following should be more strictly adhered to, if only for the sake
of being consistent.

1) Whitespace

Indents are 4 characters, tabs are 8 characters.  There should be an
emacs and vi local variables block setting at the end of each file to
adopt, enforce, and otherwise remind this convention.  The following
lines should be in all C source and header files at the end of the
file:

/*
 * Local Variables:
 * mode: C
 * tab-width: 8
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * ex: shiftwidth=4 tabstop=8
 */

A similar block can be used on source and script files in other
languages (such as Tcl, Shell, Perl, etc).  See the local variable
footer script in sh/footer.sh to automatically set/update files.

Space around operators.
  a = (b + c) * d;  /* ok */

No space around parentheses.
  while (1) { ...   /* ok */

Commas and semicolons are followed by whitespace.
  int main(int argc, char *argv[]); /* ok */
  for (i = 0; i < max; i++) { ...   /* ok */

2) Braces

Opening braces should be on the same line as their statement, close
braces should line up with that same statement.
  for (i = 0; i < 100; i++) {
    if (i % 10 == 0) {
      j += 1;
    } else {
      j -= 1;
    }
  }

3) Names

Prefer mixed-case names over underscore-separated ones. (this one is
less important, as there are vast quantities of both in the code)
Variable names should start with a lowercase letter.
  double localVariable; /* ok */
  double LocalVariable; /* bad (looks like class or constructor) */
  double _localVar;     /* bad (looks like member variable)      */

Variables are not to be "decorated" to show their type (i.e. do not
use Hungarian notation or variations thereof) with a slight exception
for pointers on occasion.  The name should use a concise, meaningful
name that is not cryptic (you typing a descriptive name is preferred
over someone else hunting down what it meant).
  char *name;    /* ok  */
  char *pName;   /* discouraged, but okay */
  char *fooPtr;  /* bad */
  char *lpszFoo; /* bad */

Constants should be all upper-case with word boundaries separated by
underscores.
  static const int MAX_READ = 2;  /* ok  */
  static const int arraySize = 8; /* bad */

4) Debugging

Compilation preprocessor defines should never change the size of structures.
  struct Foo {
  #ifdef DEBUG_CODE  // bad
    int _magic;
  #endif
  };

Use libbu's memory allocation and logging routines.  Use bu_malloc(),
bu_free(), and bu_log() instead of malloc(), free(), and printf().

---

Violations of these rules in the existing code are not excuses to
follow suit.  If code is seen that doesn't conform, it may and should
be fixed.  ;-)


DOCUMENTATION
-------------

The code should be reasonably documented, this almost goes without
saying for any body of code that is to maintain longevity.
Determining just how much documentation is sufficient and how much is
too much is generally resolved over time, but it should generally be
looked at from the perspective of "If I look at this code in a couple
years from now what would help me remember or understand it better?"
and add documentation accordingly.

All public library functions and most private or application functions
should be appropriately documented using Doxygen style comments.
Without getting into the advanced details, this minimally means that
you need to add an additional asterisk to a comment that precedes your
functions:

/** Computes the answer to the meaning of life, the universe, and
 *  everything.
 */
int the_answer() { return 42; };


TESTING
-------

The need for a more formal testing plan has become more of a pressing
issue as the size of BRL-CAD continues to grow.  As such, more
importance on various forms of testing is becoming necessary.

While specific plans for unit and black box testing are not yet
finalized, the Corredor Automation Test Suite will be used to assist
in performing cross-platform build tests, regression tests, and
various integration and operability tests.

A debug build may be specified via:

./configure --enable-debug

A profile build may be specified via:

./configure --enable-profiling

Verbose compilation warnings may be enabled:

./configure --enable-warnings

To perform a run of the benchmark suite to validate raytrace behavior:

make benchmark

To perform a run of the test suite:

make test


PATCH SUBMISSION GUIDELINES
---------------------------

All patches should be submitted in the unified diff format.  This is
generally the "-u" option to diff, and is supported by the cvs diff
command:

cvs diff -u > my_patch.diff

Where possible, diffs should be generated against the latest CVS
version available to make it easier to review and patch the diff in.
If a modification involves the addition or removal of files, those
files should be provided separately with instructions on where they
belong (or what should be removed).  If CVS cannot be used, please
provide the complete release and build number of the sources you
worked with.

Any source code that is provided must not modify or conflict with the
existing COPYING file distribution requirements.  This means that
library modifications must be LGPL-compatible and changes to
applications must be GPL-compatible.  Similarly, GPL libraries may not
be used or otherwised linked to BRL-CAD.  Contributors are asked to
only provide patches that may legally be incorporated into BRL-CAD
under the existing distribution provisions described in the COPYING
file.

Patches that are difficult to apply are difficult to accept.


BUGS
----

When a bug or unexpected behavior is encountered that cannot be
quickly fixed, it needs to be documented.  If you are already a
BRL-CAD developer, this means either making a comment in the BUGS file
or by making a formal report to the SourceForge bug tracker at:

http://sourceforge.net/tracker/?atid=640802&group_id=105292&func=browse

If the bug is complicated, will require discussion, cannot be fixed
any time soon, or if you do not have CVS commit access, the issue
should be reported to the SourceForge bug tracker.  The issues listed
in BUGS are not necessarily listed in bug tracker, and vice-versa.
The BUGS file is merely maintained as a convenience notepad of long
and short term issues for the developers only.


COMMIT ACCESS
-------------

Details on the particulars of how to interact with CVS are described
in the doc/cvspolicy.txt document.  In brief, BRL-CAD has a STABLE
branch in CVS that should always compile and run with expected
behavior on all supported platforms.  On the contrary, while the CVS
HEAD is generally always expected to compile, more flexibility is
allowed for resolution of cross-platform build issues.  Read the CVS
policy document for more details.

CVS commit access is evaluated on a person-to-person basis at the
discretion of the existing developers.  If you'd like to have commit
access, there is usually no need to ask.  Getting involved with the
other developers and making patches will generally result in automatic
consideration for CVS commit access.  If you have to ask for it, you
probably won't get it.

Those with CVS commit access have a responsibility to ensure that
other developers are following the guidelines that have been described
herein within reason.  A basic rule of thumb is: don't break anything.

While the testing process will strive to ensure consistent behavior as
changes are made, the responsibility still remains with the individual
developer to ensure that everything still compiles and runs as it
should.  At any given time, BRL-CAD should compile on all of the
primary platforms and (minimally) pass the BRL-CAD Benchmark
successfully.  If the changes are unrelated, testing should be
performed that exercise that particular change.


VERSION NUMBERS & COMPATIBILITY
-------------------------------

The BRL-CAD version number is in the configure.ac file.  The README,
ChangeLog, HISTORY files as well as a variety of documents in the doc/
directory may also make references to version numbers.

Starting with release 7.0.0, BRL-CAD has adopted a three-digit version
number convention for identifying and tracking future releases.  This
number follows a common convention where the three numbers represent:

	{MAJOR_VERSION}.{MINOR_VERSION}.{PATCH_VERSION}

All "development" builds use an odd number for the minor version.  All
"release" builds use an even number for the minor version.

The MAJOR_VERSION should only increment when it is deemed that a
significant amount of major changes have accumulated, new features
have been added, or enough significant backwards incompatibilities
were added to make a release warrant a major version increment.  In
general, releases of BRL-CAD that differ in the MAJOR_VERSION are not
considered compatible with each other.

The MINOR_VERSION is updated more frequently and serves the dual role
as previously mentioned of easily identifying a build as a public
release.  A minor version update is generally issued after significant
development activity (generally several months of activity) has been
tested and deemed sufficiently stable.  When a stable release is made,
it may (but not necessarily) be tagged as a maintenance branch in CVS
(see doc/cvspolicy.txt) with patch releases being performed on that
branch.

The PATCH_VERSION may and should be updated as frequently as is
necessary.  Every public maintenance release should increment the
patch version.  Every development version modification that is
backwards incompatible in some manner should increment the patch
version number.


MAKING A RELEASE
----------------

BRL-CAD uses a monthly iteration development cycle.  If there have
been significant changes since the previous iteration, the developers
are expected to "settle down" around the last couple days of the month
so that the source code may be verified, tested, and released.  Major
changes to the source code should not occur during these last couple
days of the iteration, only minor bug and build fixes.  A release
should then be made within the first couple days of the next month's
iteration.  Repeat, rinse, recycle.

When making a release, certain public repositories, mailing lists, and
news outlets require updating and notification.  Especially when the
major or minor version of BRL-CAD is going to be updated, it is very
important to follow and ensure that the following steps have been
successfully performed:

0) All code is committed to CVS.

1) Verify that the NEWS file includes a comment for all relevant and
significant items added since the previous release.

2) All existing manual pages and the TODO file are updated with the
latest changes.

3) Update or verify the version numbers minimally in configure.ac,
NEWS, README, and include/config_win.h (see VERSION NUMBERS &
COMPATIBILITY section) and commit the changes to the source
repository.

4) Update the ChangeLog with entries since the last release; commit
the updated ChangeLog.  Use the YYYY-MM-DD of the previous release.
Get the date from the NEWS file.

    rcs2log -h users.sourceforge.net -r "-d>YYYY-MM-DD" > ChangeLog

5) A "./configure && make" completes successfully on all platforms.

6) Perform a "make distcheck" successfully.  This will ensure that a
proper source distribution tarball may be generated and that a build
should compile properly regardless of the existence of the GNU Build
System tools (autoconf, automake, etc).

7) Tag the release using the format "rel-MAJOR-MINOR-PATCH".  See the
doc/cvspolicy.txt document for details.  e.g. cvs tag rel-7-2-4

8) Export a tagged version of the sources (required so that RCS ids
are correct):  cvs export -r rel-MAJOR-MINOR-PATCH brlcad

9) Perform another "make distcheck" on the exported/updated sources
(preferably on Mac OS X) to generate the distributable compressed
source tarballs.

10) Verify that the source distribution tarballs may be expanded; and
that they build, run, and that the file permissions are correct.

11) Use one of the source distribution tarballs to generate
platform-specific builds.  Test the build:  make test && make bench

12) Post the source and platform-specific binary distributions to
SourceForge (i.e. upload them via ftp to upload.sf.net's incoming
directory and select them on the sf.net File Release System).

13) Increment and commit the next BRL-CAD release numbers to CVS;
update the configure.ac, README, include/config_win.h, and NEWS
immediately to a developer version (odd minor or patch version number,
e.g. 7.4.1).

14) If appropriate, notify and/or update the following information
outlets with the details of the new release:

      News on the BRL-CAD website
      http://brlcad.org/
	with news details

      SourceForge Project News
      http://sf.net/projects/brlcad/
	with news details

      BRL-CAD News & Users mailing lists
      brlcad-news@lists.sourceforge.net
      brlcad-users@lists.sourceforge.net
	with news details

      CAD on Linux mailing list
      cad-linux@freelists.org
	with news details

      Freshmeat
      http://freshmeat.net/projects/BRL-CAD/
	short without news details

      upFront.ezine (if major)
      Ralph Grabowski
      ralphg@upfrontezine.com
	with news details

      CADinfo.NET (if major)
      copyboy@cadinfo.net
	with news details

      TenLinks Daily (if major)
      http://www.tenlinks.com/NEWS/tl_daily/submit_news.htm
      news@tenlinks.com
	with news details

      Slashdot (if major)
      http://slashdot.org
	short without news details

      Government Computer News (if major)
      Joab Jackson
      jjackson@gcn.com
	short without news details

15) Sit back and enjoy a beverage for a job well done.


GETTING HELP
------------

See the GETTING STARTED section above.  Basically, communicate with
the existing developers.  There is an IRC channel, e-mail mailing
lists, and on-line forums.
