OpenCSG logo

OpenCSG

The CSG rendering library

Introduction    Benefits    Prerequisites    Usage    Download    License

Introduction

OpenCSG is a library that does image-based CSG rendering using OpenGL. OpenCSG is written in C++ and supports most modern graphics hardware using Microsoft Windows or the Linux operating system.

What is CSG, anyway? CSG is short for Constructive Solid Geometry and denotes an approach to model complex 3D-shapes using simpler ones. I.e., two shapes can be combined by taking the union of them, by intersecting them, or by subtracting one shape of the other. The most basic shapes, which are not result of such a CSG operation, are called primitives. Primitives must be solid, i.e., they must have a clearly defined interior and exterior. By construction, a CSG shape is also solid then.

Image-based CSG rendering (also z-buffer CSG rendering) is a term that denotes algorithms for rendering CSG shapes without an explicit calculation of the geometric boundary of a CSG shape. Such algorithms use frame-buffer settings of the graphics hardware, e.g., the depth and stencil buffer, to compose CSG shapes. OpenCSG implements a variety of those algorithms, namely the Goldfeather algorithm and the SCS algorithm, both of them in several variants.

CSG grid

Benefits

CSG is often used as fundamental modeling technique in CAD/CAM applications. Here, image-based CSG rendering is the key to interactively manipulate CSG shapes. Since OpenCSG renders even complex CSG shapes fast, we expect it could be advantageously used in such applications.

Raytracers such as PovRay have used CSG for shape modeling since long ago. Interactive modeling toolkits for such raytracers normally just ignore CSG commands, though. OpenCSG represents a valuable addition for such applications.

Overall, up to the present CSG rendering has been hardly used in interactive applications, since the necessary algorithms are complicated and error-prone. We hope that by providing a free library that is easy to use, fast, and versatile, CSG rendering can be made more mainstream than it currently is.

CSG columns

Prerequisites

The OpenCSG library requires graphics hardware that supports the PBuffer of OpenGL. It is advantegeous if the related Render-to-Texture facility is also supported. Actually, OpenCSG uses the RenderTexture class from Mark Harris as PBuffer library.

PBuffers have been widely supported since some time ago. NVidia supports them since the Riva TNT, and ATI at least since the Radeon series. Graphics hardware from other hardware vendors, however, likely do not support PBuffers. Therefore, if you have obscure graphics hardware, you are probably out of luck and you cannot run programs using OpenCSG.

For OpenGL-Extension checking, the OpenGL Extension Wrangler Library GLEW is used.

OpenCSG is written in C++, uses namespaces and requires the STL. I do not expect major compiler incompatibilities under Windows (yes, it runs with MSVC6). Under Linux, you must use gcc-3.x.y. gcc-2.95.x will not work, since this compiler does not come with a std::map implementation, which is required internally.

To run OpenCSG well, you should have graphics hardware with lots of fill rate. NVidia graphics hardware since GeForce and ATI Radeon qualify. The OpenCSG::OcclusionQuery option obviously requires occlusion queries, which are available since Radeon 9x00 (x>=5) and GeForce3 (beware that the GeForce4MX counts as GeForce2!).

OpenCSG has been sucessfully run on Intel and AMD hardware using GeForceFX 5600, GeForce3, GeForce4MX, Radeon 9700, and TNT2 graphcs hardware (on the latter, it crawls ...). On a Radeon 9000, there are currently rendering errors in all but the standard Goldfeather rendering path. I am investigating this further, but the problem is possibly a driver issue.

CSG convace shape

Usage

The interface of OpenCSG is very easy to use. There is only a single abstract class called OpenCSG::Primitive. A Primitive object has an attribute Operation that denotes whether the primitive is intersected or subtracted. To use OpenCSG, create a derived concrete primitive class by implementing the render() method.

To actually do the CSG rendering, there is the function OpenCSG::render() that takes a std::vector<Primitive*> as argument. The render function evaluates the CSG expression given by the array of primitives and initializes the z-buffer with the proper values for the CSG expression. The color buffer remains unchanged, so afterwards, you must shade the primitives in the array using a GL_EQUAL depth function.

Note that the render function does not evaluate a generic CSG tree that also would contain unions of CSG shapes. It has been shown that a generic CSG tree can be converted into an equivalent set of CSG expressions that the render function can handle. OpenCSG does not contain the functionality for this conversion since, after all, it is a rendering library.

Here is the complete interface of OpenCSG:

namespace OpenCSG {

  enum Operation { Intersection, Subtraction };

  class Primitive {
  public:
   Primitive(Operation, unsigned int convexity);
   virtual ~Primitive();

   void setOperation(Operation);
   Operation getOperation() const;

   void setConvexity(unsigned int);
   unsigned int getConvexity() const;

   void setBoundingBox(float minx, float miny, float minz,
     float maxx, float maxy, float maxz);
   void getBoundingBox(float& minx, float& miny, float& minz,
     float& maxx, float& maxy, float& maxz) const;

   virtual void render() = 0;
  };

  enum Algorithm { Automatic, Goldfeather, SCS };
  enum DepthComplexityAlgorithm { NoDepthComplexitySampling,
    OcclusionQuery, DepthComplexitySampling };

  void render(const std::vector<Primitive*>& primitives,
    Algorithm = Automatic,
    DepthComplexityAlgorithm = NoDepthComplexitySampling);
}

The convexity of a primitive is the maximum number of front (or back) faces of the primitive at a single position. For example, the convexity of a sphere is one and the convexity of a torus is two. Actually the convexity attribute is currently only used in the standard Goldfeather algorithm. For this algorithm, a convexity too low may result in rendering errors, a convexity too high will reduce rendering performance. The other Goldfeather variants render primitives of any convexity correctly without analyzing the convexity attribute. The SCS algorithms, on the other hand, can only handle primitives that have a convexity of one, else they produce rendering errors. Hence, SCS algorithms do not check this attribute.

The bounding box of the primitive can be provided using normal device coordinates, i.e., after transforming the primitive with modelview and projection transformation. It is not necessary to set the bounding box, but it allows for various performance optimizations.

The abstract render method of the primitive is implemented in a derived class. Your implementation must not alter the modelview or projection matrix (use glPushMatrix / glPopMatrix if in doubt). Also you must not change the primary color in your implementation, since OpenCSG uses it internally. For best performance, you should only transmit vertex positions; no normals, tex coords or whatever else.

The render function performs, as said above, z-shading of a CSG expression. The content of the stencil buffer is destroyed when handling concave primitives or when using the DepthComplexitySampling strategy.

The Algorithm parameter specifies the method used for CSG rendering. Besides Goldfeather and SCS, you can also choose Automatic: This setting chooses the Goldfeather algorithm if the primitive array contains concave primitives, else it chooses SCS. The automatic setting also sets the DepthComplexityAlgorithm (NoDepthComplexitySampling for arrays with few primitives, else OcclusionQuery or at the last resort DepthComplexitySampling).

If the Automatic setting is not used, the DepthComplexityAlgorithm parameter specifies the strategy for profiting from depth complexity.

CSG grid

Download

Download OpenCSG-0.9.zip. The archive contains all required helper libraries, i.e., also RenderTexture and GLEW. It comes with makefiles for Linux and with project files for MSVC6 / VS2003.

CSG columns

License

OpenCSG is copyrighted by the Hasso-Plattner-Institute at the University of Potsdam (HPI), Germany, and by Florian Kirsch.

You can license OpenCSG by terms of the GNU GPL, Version 2. This means that you may use and link against OpenCSG (a) only if you release the complete source code of your application or library for free and (b) only if you release it under the GPL license.

If you do not want to release your source code unter terms of the GPL, you can't use and link against OpenCSG by licensing it unter GPL. In this case, e.g., if you want to use OpenCSG in a proprietary application or library, you can always ask for a commercial license and use it for development and production purposes.

According to the GPL, you are free to modify and redistribute OpenCSG under terms of the GPL. We welcome contribution of your modifications to OpenCSG, however to let us integrate your modifications into OpenCSG, you must assign the copyright of the modifications to the HPI, Florian Kirsch. In other words, your modifications to OpenCSG should not hinder us to distribute OpenCSG under other, non-free licenses.

Note that OpenCSG comes with code that is not under copyright of the HPI or Florian Kirsch. These are GLEW and the RenderTexture class. These libraries are licensed under the terms of their respective authors.

CSG concave shape

© 2002, 2003 Hasso-Plattner-Institute Potsdam, Florian Kirsch.
Last change: 24.09.2003