0% found this document useful (0 votes)
100 views7 pages

CSG Report

1) The document discusses an implementation of constructive solid geometry (CSG) using binary space partitioning trees (BSP trees). BSP trees allow efficient Boolean operations like unions, intersections, and differences to be performed on complex 3D models. 2) The algorithm involves creating BSP trees from the input 3D geometries, then merging two trees by recursively splitting one tree at the planes of the other. 3) Examples are given of performing Boolean operations on models like a cube, sphere, and cylinders to build objects like a single layer of a gyrocube. CSG allows such complex models to be represented with simple operations on primitives.

Uploaded by

khalil alhatab
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views7 pages

CSG Report

1) The document discusses an implementation of constructive solid geometry (CSG) using binary space partitioning trees (BSP trees). BSP trees allow efficient Boolean operations like unions, intersections, and differences to be performed on complex 3D models. 2) The algorithm involves creating BSP trees from the input 3D geometries, then merging two trees by recursively splitting one tree at the planes of the other. 3) Examples are given of performing Boolean operations on models like a cube, sphere, and cylinders to build objects like a single layer of a gyrocube. CSG allows such complex models to be represented with simple operations on primitives.

Uploaded by

khalil alhatab
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

24-681: Computer-Aided Design

Spring 2013

Constructive Solid Geometry Using BSP Tree


Christian Segura1 , Taylor Stine2 , Jackie Yang3

Abstract
Constructive solid geometry (CSG) is a pivotal component of CAD and CAE packages. CSG allows us to represent complex
shapes and models as a series of Boolean operations between primitives. For example, punching a hole through a cube
would be difficult to represent with an implict or explicit funciton. The CSG algorithm we have developed allows something
like this to be represented as a simple Boolean operation between a cube and cyllinder. Here we present an implementation
of CSG using an efficient spatial datastructure called a binary space partitioning tree (BSP tree). These BSP trees allow us
to perform Boolean operations on complex models in a matter of milliseconds. In this paper, we validate our concept and
implementation by performing Boolean operations on a series of intracate models. The results show our algorithm is efficient
and accurate.
Keywords
Computer-aided design(CAD) — Constructive solid geometry(CSG) — Binary space partitioning(BSP)
1 [email protected]
2 [email protected]
3 [email protected]

Department of Mechanical Engineering, Carnegie Mellon University, Pittsburgh, United States

Contents intersection of a cube and sphere, the union of three differ-


ently oriented cylinders, and then finally subtract the cylinders’
1 Problem Summery 1 composite model from the first one to build a 3D single layer
2 Algorithm 2 of a gyrocube. Figure 1 shows the process described above.
CSG also allows efficient detection of various geometric char-
2.1 Create BSP tree . . . . . . . . . . . . . . . . . . . . . . . . . 2
acteristics within 3D models, such collision detection and
2.2 Merge two trees . . . . . . . . . . . . . . . . . . . . . . . . . 4
water tightness. Collision Detection (Figure 2) can very often
3 Results & Discussion 6 be a computationally expensive process. Using CSG reduces
4 Future Work 6 the collision detection computational cost by instead spend-
ing those resources up front in creating a more efficient data
References 7
structure which yields faster results when testing for intersec-
tions/collisions between models. Furthermore, some model
1. Problem Summery characteristics can be inherited from base geometries after
Boolean operations. One can easily check if a model is water
Constructive Solid Geometry is a solid modeling technique tight by checking if the components used to create it are also
that allows a user to create a complex surfaces or volumes by water-tight. This prove to be very helpful when characterizing
using Boolean operators. In doing so the user can combine certain geometric information which is not immediately obvi-
different geometry as they seem fit to generate a result. ous or is computationally expensive to calculate on a newly
Multiple techniques exist in CAD packages and graphics created model. Another important use for CSG is efficiently
applications which allow the creation of geometric models. determining the visibility of models relative to each other
CAD packages and computer graphics applications tackle with a changing viewpoint. This offers graphics processors a
different geometry problems with different approaches. For powerful and efficient method to render front objects without
instance, voxel modeling can be used to represent three di- the occlusion of the back ones. The binary space partition-
mensional information, while boundary representation can ing used for CSG Boolean operations facilitates this function
be used for mesh generation. However, the best technique to (Figure 3).
create geometries from existing geometries is CSG. CSG can be used for multiple applications, but must re-
CSG offer many advantages over other computational ge- main watchful of its pitfalls. CSG can be implemented in
ometry methods. The main one is that it allows the user to various manners, but the programmers must ensure that com-
perform basic operations on simple models that result in com- putational costs don’t exceed the processing power or allo-
plex yet accurate geometric objects. For instance creating a cated loading time. The smarter method encourages data
single layer of a gyrocube, would be prove to be quite com- restructuring inside a BSP tree, which ensures the compu-
plex with other methods. With CSG, we can easily find the tational cost is paid for up front instead of doing so when
Constructive Solid Geometry Using BSP Tree — 2/7

Figure 1. Example of CSG tree [6]

Figure 3. Render objects using BSP tree


Figure 2. Collision detection [7]

performing each of the different Boolean operations.

2. Algorithm
One of the key problems in computer aided design and graph-
ics is determining what objects are visible relative to one
another, with a constantly changing viewpoint (Figure 4).
Furthermore, the problem of surface to surface interference
is difficult to classify for models with a complex geometry.
When a scene or rendering consists of several models, this
problem becomes even more difficult. Figure 4. Concept of CSG in 3D
In order to resolve these issues, graphics software engi-
neers utilize a spatial data structure known as a binary space
partitioning tree (a.k.a. BSP tree). The BSP tree represents a side of the plane, f1 (p− ) < 0. Using this property of implicit
way to recursively divide a scene along two sides of a plane, planes we can define on which side of the plane a triangle
until some partitioning criterion is met. There are many simi- (consisting of three points) lies. Initially, let us assume that all
lar data structures known to computer graphics, (octrees, k-d of the triangles in our scene are either on one side of our parti-
tree, bounding box hierarchy etc.) but BSP trees provide us tioning plane defined by our triangle (Figure 5, Figure 6). We
with the most flexibility in partitioning our scene. That flexi- can pick one of the triangles and partition the other triangles
bility results from our ability to orient the partitioning plane about it with pseudo code in Algorithm 1.
in any direction, without being constrained by orthogonality This example can be generalized to many object, again
as in octrees or k-d trees. assuming the simple case where none of our polygons span our
dividing plane. In this example, f1 (p) is the implicit function
2.1 Create BSP tree of a plane created by triangles with counter clockwise vertices
The construction of a BSP tree is simple to visualize. Image a, b, and c:
a scene consisting of three triangles. The key properties of
the implicit planes these triangles define in 3D space is that f1 (p) = ((b − a) × (c − a)) · (p − a) = 0 (1)
for all points on one side of the plane p+ we can easily create
a function f1 (p+ ) > 0. Similarly for all points on the other However it can be faster to store the values of the implicit
Constructive Solid Geometry Using BSP Tree — 3/7

plane equation in the form:

Ax + By +Cz + D = 0 (2)

This is the same expression, and can be faster to solve


than equation (1). Here the constant D is equal to:

D = −n · a (3)

Storing the equation in this form can reduce some com-


putation time associated with taking the cross product. Thus,
this naturally leads to the follow pseudo-code for BSP tree
construction shown in Algorithm 2.

(a) Multi-plane in 3D space (b) BSP tree representation Algorithm 2 BSP tree initial pseudo code
Require: tree.node = triangles[0]
Figure 5. BSP tree creation (without intersection) 1: for i = 2 → N do
2: tree.add(triangles[i])
3: end for
4: function ADD (triangle T)
5: if f (a) < 0 ∧ f (b) < 0 ∧ f (c) < 0 then
6: if back-subtree does not exist then
7: create back-subtree
8: back-subtree.node = T
9: else
10: front-subtree.add(T)
11: end if
12: else if f (a) > 0 ∧ f (b) > 0 ∧ f (c) > 0 then
13: if front-subtree does not exist then
14: create front-subtree
15: front-subtree.node = T
16: else
17: front-subtree.add(T)
(a) Multi-plane in 3D space (b) BSP tree representation 18: end if
19: end if
Figure 6. BSP tree creation (with intersection) 20: end function

From our above constraints on building the tree (i.e. none


of the triangles span the tree) we have not yet defined how
to handle the case of when some functions of the vertices of
the triangle are positive, and others are negative. In this case,
the only thing we can do is split the triangle into three new
Algorithm 1 Triangle partition pseudo code triangles (Figure 7).
Require: partition = triangles[0]
1: for triangle = triangles[begin → end] do
2: for p = points[in M] do
3: if f1 < 0 then
4: return in back of plane
5: else if f1 > 0 then
6: return in front of plane
7: end if
8: end for
9: end for Figure 7. Principle to split a triangle

Assuming that a and b are always on one side of the


triangle and c is on the other the new triangles will always be
Constructive Solid Geometry Using BSP Tree — 4/7

equal to:
T1 = (a, b, A)
T2 = (b, B, A) (4)
T3 = (A, B, c)
It is clear from this representation that a special case will Algorithm 3 BSP tree final pseudo code
emerge when the triangle is split perfectly down the middle.
Although rare, We will account for this by not splitting the Require: f a = f (a), f b = f (b), f c = f (c)
triangles if this occurs. Thus our final implementation of the 1: function ADD (triangle T)
BSP tree creation is shown in Algorithm 3. 2: if | f a| < ε then
The last component of building our BSP tree is computing 3: fa = 0
A and B. Computing the A and B intersection points consist 4: end if
of simply solving a ray-plane intersection equation: 5: if | f b| < ε then
6: fb = 0
7: end if
p(t) = a + t(c − a) 8: if | f a| < ε then
n · (a + t(c − a)) + D = 0 9: fb = 0
n·a+D (5)
t =− 10: end if
n · (c − a) 11: if f a ≤ 0 ∧ f b ≤ 0 ∧ f c ≤ 0 then
A = a + t(c − a)
12: if back-subtree does not exist then
Our creation algorithm for a BSP tree is now complete. 13: created back-subtree
14: back-subtree.node = T
2.2 Merge two trees 15: else
Because of their ability to divide a series of polygons by an 16: back-subtree.add(T)
arbitrarily chosen plane, BSP trees offer the ideal data struc- 17: end if
ture to perform Boolean operations on arbitrary pieces of 18: else if f a ≥ 0 ∧ f b ≥ 0 ∧ f c ≥ 0 then
geometry. In order to perform these operations, we have de- 19: if front-subtree does not exist then
veloped an algorithm that ”merges” two BSP trees. Assuming 20: create front-subtree
a simple case of just two models in a scene with which we 21: front-subtree.node = T
want to perform Boolean operations, the first thing we need 22: else
to do is create BSP trees for both of the geometries. These 23: front-subtree.add(T)
trees are created independently for each geometry initally, 24: end if
so we will only be testing polygons in one model for each 25: else
BSP tree creation. When we create these BSP trees, instead 26: cut the triangle
of simply arbitrarily choosing planes to divide the polygons 27: end if
by, we will choose to divide the polygons by the polygons 28: compute A
on the surface of the model. Thus these BSP trees allow us 29: compute B
to create an efficient structure to traverse the boundaries of 30: T1 = (a, b, A)
a complicated mesh. Now that we have two representations 31: T2 = (b, B, A)
of the boundaries of the models, we begin to merge them by 32: T3 = (A, B, c)
traversing one of the trees to obtain a list of polygons that 33: if f c ≥ 0 then
represent the surface boundary of one of the models. We use 34: back-subtree.add(T1 )
this list of polygons because it contains new polygons created 35: back-subtree.add(T2 )
by splitting the polygons of the model by the dividing planes 36: front-subtree.add(T3 )
chosen when creating the tree. These could not be captured if 37: else
we just used the list of polygons provided with the model for 38: front-subtree.add(T1 )
the next step in the merging algorithm. The traversal of the 39: front-subtree.add(T2 )
BSP tree is quite simple as shown in Algorithm 4. 40: back-subtree.add(T3 )
This will give us a list of polygons represented as a pre- 41: end if
order traversal of the tree. Now that we have a list of polygons 42: end function
from the tree that represents model A, we have to push these
polygons through the tree of model B so that we can see how
they will be classified according to B’s dividing polygons.
Algorithm 5 looks very similar to the add function listed
above. This algorithm assumes that we are working with
models made up of only triangles.
Constructive Solid Geometry Using BSP Tree — 5/7

Algorithm 4 Traversal of the BSP tree


1: function TRAVERSE(tree)
2: if tree does not exist then
3: exit
4: end if Algorithm 5 Push polygons from tree to model
5: polygon-list.add(tree.polygon) 1: for i = 2 → N do
6: traverse(tree.back-subtree) 2: insert(treeB .root, Atriangles [i])
7: traverse(tree.front-subtree) 3: end for
8: return polygon-list 4: function INSERT(Node node, triangle T)
9: end function 5: f a = f (a)
6: f b = f (b)
7: f c = f (c)
In Algorithm 5, instead of adding these triangles to the 8: if | f a| < ε then
tree, we are traversing the tree to see where they belong in the 9: fa = 0
BSP representation of the model. If we get to a point where 10: end if
the triangle is classified as being behind the current dividing 11: if | f b| < ε then
plane and there are no there are no other dividing planes in 12: fb = 0
the back-subtree of the BSP tree, then we can classify this 13: end if
triangle as being inside of the model. The same can be said 14: if | f c| < ε then
about a triangle completely in front of the dividing plane. 15: fc = 0
An interesting case emerges when we find that the dividing 16: end if
plane we are testing splits the triangle. In this case, we cannot 17: if f a ≤ 0 ∧ f b ≤ 0 ∧ f c ≤ 0 then
yet classify the newly split triangles as completely inside or 18: if back-subtree does not exist then
outside of the polygon, because we could have split a triangle 19: inside-model.add(T)
that may intersect the dividing plane, but isn’t split by the 20: else
boundary of the model. The only way to classify these newly 21: insert(node.back-subtree, T)
created triangles is to push them through the tree again. Once 22: end if
all of the triangles have been inserted, we now have a list of 23: else if f a ≥ 0 ∧ f b ≥ 0 ∧ f c ≥ 0 then
triangles from model B that are inside/outside of model A. 24: if front-subtree does not exist then
We perform this same procedure for model A, to obtain two 25: outside-model.add(T)
similar lists. Once we have these lists, it is a trivial matter 26: else
to combine them to obtain the Boolean operations we desire 27: insert(node.front-subtree, T)
(Figure 8). 28: end if
29: else
30: cut the triangle
31: end if
32: compute A
33: compute B
34: T1 = (a, b, A)
35: T2 = (b, B, A)
36: T3 = (A, B, c)
37: if f c ≥ 0 then
38: insert(node.back-subtree, T1 )
39: insert(node.back-subtree, T2 )
40: insert(node.front-subtree, T3 )
41: else
Figure 8. Merge two trees [8] 42: insert(node.front-subtree, T1 )
43: insert(node.front-subtree, T2 )
44: insert(node.back-subtree, T3 )
The reason we choose to use BSP trees and use Algo-
45: end if
rithm 5 is because of the efficiency of merging the two trees.
46: end function
The operation of merging two trees takes milliseconds, and
can be done in O(n log n) efficiency in the best case and O(n2 )
in the worst case where we have a very unbalanced tree. The
most computationally expensive portion of the Algorithm 5
comes from actually creating the trees. For convex polygons
Constructive Solid Geometry Using BSP Tree — 6/7

Algorithm 5 can take up to O(n2 ) time, because this creates


a very unbalanced tree. For models with concavity, the cre-
ation of Algorithm 3 can get down to O(n log n) efficiency,
but can take longer to allocate memory for the new triangles
created by the partitioning plane. This is much faster than
the O(n3 ) case of comparing all planes to all other planes of
a naive implementation of model Boolean operations. The
pre-processing time is the whole purpose of BSP trees. They
are used to pre-cache the information we need in the pre-
processing step, to allow for quick traversal when we need to
render, merge, or test for collisions. This is the reason they
are most often used in video games and CAD systems. Their
traversal efficiency allows us to create the Boolean operations
for these models in a matter of seconds. Figure 10. CSG of cube & Android

3. Results & Discussion


We downloaded multiple 3D models from the web1 and put
this algorithm to the test in the C++ programming language.
They ranged from highly simple 3D shapes like cubes and
toruses (Figure 9), to fully complex video game characters
models (Figure 10, Figure 11). For each model, we created a
BSP tree structure as described in the algorithm above, and
then merged each model’s tree according to the Boolean op-
eration performed on the pair of models. We tested all the
operations, including union, intersection, differences and xor
on our models. We used OpenGL to render each model sepa-
rately on screen first, and then rendered each of the Boolean
operation results. Notice that our meshes only consist of sur- Figure 11. CSG of torus & dragon
face polygons and contain no volumetric information. As
such, you can see into or through our model result who oper-
ations cut through the base models. Nonetheless, the results the Boolean operation would yield results with minor geom-
were quite promising. etry artifacts. For instance, when creating the intersection
between the cube and the werewolf, we get a result which is
not quite as expected (as displayed in Figure 12). The artifacts
that appear in some of our results appear to manifest them-
selves when operations are performed on objects with low
polygon count. We believe that this occurs due to the lower
resolution of one model relative to the other, and thus when
the BSP trees of both models are merged, we occasionally are
left with extraneous triangles that must get pushed through
the BSP tree more than once but end up getting catalogued
incorrectly. Nonetheless, the operation combinations we per-
formed impressive results which looked almost identical to
results in high computer graphics and computer-aided design
applications.

Figure 9. CSG of cube & torus 4. Future Work


This project has potential for future work and progress. Due
For many of the simple shapes, our results were very ac- to the brief time period given to the team to work on this
curate. For instance, CSG Boolean operations between cubes project, we limited our code to perform operations on a single
and toruses resulted in error-free models. However, for more pairs of models. Furthermore, we only utilized surface mesh
complicated shapes, such as the different character models, information as inputs and outputs to our algorithm to facili-
tate its implementation. In the future, we could potentially
1 http://www.turbosquid.com be able to perform any number of operations on a larger set
Constructive Solid Geometry Using BSP Tree — 7/7

Acknowledgments
Thanks to Professor Kenji Shimada for his excellent lectures
which gave us enough background knowledge to start and fin-
ish this project. We appreciate his advice during the semester.

References
[1] B. Naylor, J. Amanatides and W. Thibault, Merging BSP
Trees Yields Polyhedral Set Operations, in Proc. Siggraph
’90, Computer Graphics 24(4), pp 115-124, 1990.
[2] Miklo Lysenko, Roshan D’Souza and Ching-Kuang Shene,
in Improved Binary Space Partition Merging, CAD, Vol. 40,
No. 12, pp. 1113-1120, 2009.
[3] Shirley, Peter et. al, in Fundamentals of Computer Graph-
Figure 12. CSG of werewolf & cube
ics, 3rd ed. Wellesley: A K Peters, 2009.
[4] Tom Duff, Interval arithmetic recursive subdivision
of models consisting of more than two geometries. In doing for implicit functions and constructive solid geometry,
so, we would enable Boolean operation chaining, where we inSIGGRAPH ’92, 1992.
would created composite models from our base models, and [5] H. Jones, in Computer Graphics.: Through Key Mathe-
then further perform other Boolean operations on our compos-
matics, pp. 227, 2001.
ite models for more impressive and complex results. In the
[6] https://en.wikipedia.org/wiki/
next stage of our software, we would like to take use voxel
representations of our models as input and output to our CSG Constructive_solid_geometry
algorithm. In doing so, we allow OpenGL to also render the [7] http://glscene.sourceforge.net/
volumetric information after performing the Boolean opera- oldsite/Gallery/boxedin_h.jpg
tions on the pair of models. This would enable a higher level [8] http://ars.els-cdn.com/content/image/
of accuracy and an easier visual understanding of our results
1-s2.0-S0010448508002030-gr3.jpg
since we would no longer be rendering just the surfaces of the
[9] http://exocortex.com/products/implosia
models, but the a solid in itself (Figure 13). Our algorithm,
though efficient, lacks any optimization that can be achieved [10] http://www.cs.cmu.edu/afs/cs/
with tree balancing or parallel programming. Implementing academic/class/15462-s13/www
these would further speed up our algorithm execution. Lastly,
we would look for different methods to eliminate the geom-
etry artifacts that appear in some of the results. We could
automatically increase the number of polygons in a model by
splitting surface faces into smaller polygons and get rid of
these artifacts entirely. Furthermore, we could attempt to run
the algorithm on the polygons themselves instead of having
to split the all non-triangular polygons into triangles. This
would also speed up the process and help eliminate the root
of the artifacts problem.

Figure 13. Render solid model instead of surfaces [9]

You might also like