Skip to content

Commit a99c049

Browse files
committed
Initial commit of quartet project source code.
1 parent 7691c23 commit a99c049

47 files changed

Lines changed: 306613 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
*.slo
33
*.lo
44
*.o
5-
*.obj
5+
#*.obj
6+
obj/*
7+
obj_debug/*
68

79
# Precompiled Headers
810
*.gch
@@ -26,3 +28,8 @@
2628
*.exe
2729
*.out
2830
*.app
31+
quartet
32+
quartet_release
33+
view_tet
34+
view_tet_release
35+

Makefile

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Makefile for quartet
2+
#
3+
# This Makefile depends on a file called "Makefile.defs" which contains
4+
# platform-specific definitions.
5+
#
6+
# To build quartet, first run "make depend" (which relies on g++ version 3.1 or
7+
# higher) and then either "make" (equivalent to "make debug") or "make release".
8+
#
9+
# This is for GNU make; other versions of make may not run correctly.
10+
11+
MAIN_PROGRAM = quartet
12+
SRC = predicates.cpp \
13+
geometry_queries.cpp \
14+
sdf.cpp \
15+
trimesh.cpp \
16+
tet_mesh.cpp \
17+
feature.cpp \
18+
read_obj.cpp \
19+
tet_quality.cpp \
20+
match_features.cpp \
21+
optimize_tet_mesh.cpp \
22+
make_signed_distance.cpp \
23+
make_tet_mesh.cpp \
24+
main.cpp
25+
26+
VIEWER_PROGRAM = view_tet
27+
VIEWER_SRC = gluvi.cpp \
28+
view_tet.cpp \
29+
feature.cpp \
30+
read_obj.cpp \
31+
predicates.cpp \
32+
geometry_queries.cpp \
33+
tet_mesh.cpp \
34+
tet_quality.cpp
35+
36+
37+
SRC_ALL = $(SRC) $(VIEWER_SRC)
38+
39+
include Makefile.defs
40+
41+
# object files
42+
RELEASE_OBJ = $(patsubst %.cpp,obj/%.o,$(notdir $(SRC)))
43+
VIEWER_RELEASE_OBJ = $(patsubst %.cpp,obj/%.o,$(notdir $(VIEWER_SRC)))
44+
DEBUG_OBJ = $(patsubst %.cpp,obj_debug/%.o,$(notdir $(SRC)))
45+
VIEWER_DEBUG_OBJ = $(patsubst %.cpp,obj_debug/%.o,$(notdir $(VIEWER_SRC)))
46+
47+
.PHONY: all
48+
all: debug
49+
50+
# how to make the main target (debug mode, the default)
51+
$(MAIN_PROGRAM): $(DEBUG_OBJ)
52+
$(LINK) $(DEBUG_LINKFLAGS) -o $@ $^ $(LINK_LIBS)
53+
54+
# how to make the main target (release mode)
55+
$(MAIN_PROGRAM)_release: $(RELEASE_OBJ)
56+
$(LINK) $(RELEASE_LINKFLAGS) -o $@ $^ $(LINK_LIBS)
57+
58+
# how to make the viewer application (debug mode, the default)
59+
$(VIEWER_PROGRAM): $(VIEWER_DEBUG_OBJ)
60+
$(LINK) $(DEBUG_LINKFLAGS) -o $@ $^ $(LINK_LIBS) $(VIEWER_LIBS)
61+
62+
# how to make the viewer application (release mode)
63+
$(VIEWER_PROGRAM)_release: $(VIEWER_RELEASE_OBJ)
64+
$(LINK) $(RELEASE_LINKFLAGS) -o $@ $^ $(LINK_LIBS) $(VIEWER_LIBS)
65+
66+
# how to compile the predicates.cpp source file
67+
# This is different because optimization must be disabled
68+
# (at least, according to the TetGen source... not sure if it's true or not)
69+
obj/predicates.o: src/predicates.cpp
70+
$(CC) -c $(RELEASE_FLAGS) -O0 -o $@ $^
71+
obj_debug/predicates.o: src/predicates.cpp
72+
$(CC) -c $(DEBUG_FLAGS) -O0 -o $@ $^
73+
74+
75+
.PHONY: release
76+
release: $(MAIN_PROGRAM)_release $(VIEWER_PROGRAM)_release
77+
78+
.PHONY: debug
79+
debug: $(MAIN_PROGRAM) $(VIEWER_PROGRAM)
80+
81+
# how to compile each file
82+
.SUFFIXES:
83+
obj/%.o:
84+
$(CC) -c $(RELEASE_FLAGS) -o $@ $<
85+
obj_debug/%.o:
86+
$(CC) -c $(DEBUG_FLAGS) -o $@ $<
87+
88+
# cleaning up
89+
.PHONY: clean
90+
clean:
91+
-rm -f obj/*.o $(MAIN_PROGRAM) $(VIEWER_PROGRAM) obj_debug/*.o $(MAIN_PROGRAM)_release $(VIEWER_PROGRAM)_release *core
92+
93+
# dependencies are automatically generated
94+
.PHONY: depend
95+
depend:
96+
-mkdir obj
97+
-rm -f obj/depend
98+
$(foreach srcfile,$(SRC_ALL),$(DEPEND) -MM src/$(srcfile) -MT $(patsubst %.cpp,obj/%.o,$(notdir $(srcfile))) >> obj/depend;)
99+
-mkdir obj_debug
100+
-rm -f obj_debug/depend
101+
$(foreach srcfile,$(SRC_ALL),$(DEPEND) -MM src/$(srcfile) -MT $(patsubst %.cpp,obj_debug/%.o,$(notdir $(srcfile))) >> obj_debug/depend;)
102+
103+
-include obj/depend
104+
-include obj_debug/depend

Makefile.defs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# This file is included into the main Makefile, providing it with
2+
# local machine settings.
3+
# Most of it is platform-specific compilers, flags, and libraries.
4+
# See below examples for which variables should be defined.
5+
6+
# For example, on a Linux PC this will likely work:
7+
DEPEND = g++
8+
CC = g++ -Wall
9+
RELEASE_FLAGS = -O3 -DNDEBUG -funroll-loops
10+
DEBUG_FLAGS = -g
11+
LINK = g++
12+
LINK_LIBS = -lm
13+
VIEWER_LIBS = -lGL -lGLU -lglut
14+
15+
# Should work for Mingw (with freeglut installed)
16+
#DEPEND = g++
17+
#CC = g++ -Wall
18+
#RELEASE_FLAGS = -O3 -DNDEBUG -funroll-loops
19+
#DEBUG_FLAGS = -g
20+
#LINK = g++
21+
#LINK_LIBS = -lm
22+
#VIEWER_LIBS = -lopengl32 -lglu32 -lfreeglut
23+
24+
# On Mac OS X (on a G5), this probably will work:
25+
#DEPEND = g++
26+
#CC = g++ -Wall
27+
#RELEASE_FLAGS = -DNDEBUG -fast # add -mcpu=7450 for a G4, or -mcpu=750 for a G3 since -fast enables 970(G5) instructions by default
28+
#DEBUG_FLAGS = -g
29+
#LINK = g++
30+
#LINK_LIBS = -lm -lobjc
31+
#VIEWER_LIBS = -framework OpenGL -framework GLUT

README

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
Quartet
2+
*******
3+
4+
A tetrahedral mesh generator based on Jonathon Shewchuk's isosurface stuffing
5+
algorithm in combination with the A15 acute tetrahedral tile.
6+
7+
written by:
8+
Robert Bridson (www.cs.ubc.ca/~rbridson)
9+
Crawford Doran (www.crawforddoran.com)
10+
--------------------------------------
11+
12+
13+
Overview
14+
==========
15+
16+
Quartet converts a watertight triangle mesh into a high-quality uniform
17+
tetrahedral mesh that closely approximates the geometry, up to the curvature
18+
implied by the specified grid sampling (dx). Optionally, the tetrahedral mesh
19+
can be warped to match sharp features on the input, and also improved by a
20+
quality optimization pass.
21+
22+
23+
Building Quartet
24+
=================
25+
26+
1) It may be necessary to edit Makefile.defs in order to ensure that
27+
platform-specific variables are set correctly. These include the compiler,
28+
linker, and all flags associated with them, including libraries.
29+
2) Run 'make depend'
30+
3) Run 'make' and/or 'make release' ('make' is equivalent to 'make debug')
31+
32+
33+
Running Quartet
34+
==================
35+
36+
Quartet is run from the command line with the following syntax:
37+
38+
quartet <input.obj> <dx> <output.tet> [-f <feature.feat>] [-a <angle_threshold>]
39+
[-s <surface.obj>] [-i] [-o]
40+
41+
- <input.obj> is the OBJ file containing the surface to be converted to a
42+
tetrahedral mesh.
43+
- <dx> is the grid spacing used in the isosurface stuffing algorithm. The
44+
generated tetrahedra will be approximately this size.
45+
- <output.tet> is a path to the file where the resulting tetrahedral mesh will
46+
be saved.
47+
48+
The optional flags have the following effects:
49+
-f <features.feat> -- The given file <features.feat> contains lists of
50+
points and edges indicating sharp corners and ridges
51+
in the input. The output mesh will resolve these
52+
features as well as possible.
53+
-a <angle_threshold> -- Auto-detects sharp features in the input. Edges with
54+
a dihedral angle smaller than <angle_threshold> degrees
55+
will be resolved in the output as well as possible.
56+
In addition, these features will be written to a file
57+
called 'auto.feat' (which can then be fed to the -f
58+
option in future executions).
59+
-s <surface.obj> -- The boundary of the resulting tetrahedral mesh is
60+
written to <surface.obj>. This is largely for
61+
convenience of visualizing the result.
62+
-i -- Intermediate stages of the mesh generation process are
63+
saved to disk in files named 'N_*_.tet' where N is the
64+
numbering of the steps.
65+
-o -- Perform quality optimization on the resulting
66+
tetrahedral mesh.
67+
68+
Example inputs can be found in the 'meshes' directory. For the inputs with
69+
sharp features, corresponding .feat files are provided.
70+
71+
Example usages:
72+
quartet dragon.obj 0.01 dragon_01.tet -o -s dragon.obj
73+
quartet fandisk.obj 0.1 fandisk_1.tet -f fandisk.feat
74+
quartet block.obj 0.5 block_5.tet -a 110.0 -o
75+
76+
77+
Running view_tet
78+
==================
79+
80+
We have included an OpenGL viewer application for visualizing resulting tet
81+
meshes. The viewer is called view_tet, and can be called with the following
82+
syntax:
83+
84+
view_tet <input.tet> [-s] [-f <features.feat>] [-p (x|y|z)<cutting-plane-pos>]*
85+
[-w <num_tets>]
86+
87+
Here, <input.tet> is the TET file produced by quartet containing the tet mesh.
88+
89+
The optional flags have the following effects:
90+
-s -- Assume that <input.tet> is actually
91+
<input.obj> and read it in as a surface
92+
mesh from an OBJ file.
93+
-f <features.feat> -- Displays the sharp features in the file
94+
<features.feat> alongside the mesh.
95+
-p (x|y|z)<cutting-plane-pos> -- Specifies a plane to cut the mesh so the
96+
viewer can see "inside" of it. The plane is
97+
specified by which coordinate axis is its
98+
normal and its position along that axis.
99+
Multiple planes can be specified with multiple
100+
occurrences of this flag.
101+
-w num_tets -- Draw the mesh so that the <num_tets>
102+
worst-quality tetrahedra are highlighted.
103+
104+
Example usages:
105+
view_tet block.tet -p x0.0
106+
view_tet dragon.obj -s
107+
view_tet fandisk.tet -f fandisk.feat -w 10
108+
109+
Once view_tet is running, the viewer can be controlled with the following
110+
inputs:
111+
112+
Shift+LeftMouseButton -- Rotate camera
113+
Shift+RightMouseButton -- Zoom camera
114+
Shift+MiddleMouseButton -- Pan camera
115+
116+
117+
118+
Source Code overview
119+
======================
120+
121+
The following files make up the quartet source:
122+
123+
Utilities / Data Structures:
124+
125+
util.h
126+
- a bunch of small useful functions
127+
128+
vec.h
129+
- a convenience wrapper around fixed-length arrays (for vectors in 3D etc.)
130+
131+
array3.h
132+
- a convenience wrapper around STL vectors to get 3D arrays
133+
134+
sdf.h/cpp
135+
- a signed-distance-field data structure for working with level sets
136+
137+
read_obj.h/cpp
138+
- code to read in a Wavefront .OBJ file
139+
140+
trimesh.h/cpp
141+
- a simple half-edge triangle mesh data structure
142+
143+
tet_mesh.h/cpp
144+
- an index-based tetrahedral mesh data structure. Maintains incidence
145+
relationships as necessary for fast adjacency queries.
146+
147+
features.h/cpp
148+
- Data structures representing sharp features of a triangle mesh and
149+
aggregations of those features (called FeatureSets)
150+
151+
152+
Meshing Functions:
153+
154+
geometry_queries.h/cpp
155+
- some simple and not-so-simple geometric operations needed for creating
156+
signed distance functions from triangle meshes.
157+
Uses Jonathan Shewchuk's robust geometric predicates code, found in
158+
predicates.cpp (http://www.cs.cmu.edu/~quake/robust.html).
159+
160+
make_signed_distance.h/cpp
161+
- code for robustly creating a fairly accurate signed distance function
162+
of a watertight triangle mesh, sampled on a regular 3D grid.
163+
164+
make_tet_mesh.h/cpp
165+
- code to create a quality tetrahedral mesh of the interior of a level set
166+
167+
tet_quality.h/cpp
168+
- functions for measuring quality of tetrahedra based on various metrics
169+
170+
match_features.h/cpp
171+
- code to restore desired sharp features onto a tetrahedral mesh
172+
173+
optimize_tet_mesh.h/cpp
174+
- code to improve the overall quality of a given tetrahedral mesh. Uses as
175+
much data from the meshing step (ie: sdf, sharp features, etc.) as possible.
176+
177+
main.cpp
178+
- quartet command-line program
179+
180+
181+
Viewer Application:
182+
183+
gluvi.h/cpp
184+
- code for creating a simple generic OpenGL viewer application
185+
186+
view_tet.cpp
187+
- view_tet main code file for viewing tet meshes
188+

TODO

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
- A better build setup (eg: cmake)
2+
3+
- Iteratively alternate between optimization and progressive feature matching
4+
5+
- Alternative feature matching strategies
6+
- Move neighbors when snapping vertex (ie: energy/spring model,
7+
displacement kernel).
8+
- Snap lattice vertices to features before doing isosurface stuffing.
9+
- OR Snap lattice vertices to feature endpoints (not full features)
10+
before doing isosurface stuffing.
11+
12+
- Ensure optimality of path search
13+
- Right now not guaranteed to be optimal because the tet inversion test
14+
depends on the path taken to a particular vertex, not just the edges
15+
and weights of the graph.
16+
17+
- Use tet quality metrics to choose optimal paths during edge snapping
18+
(instead of just minimizing the distance that vertices are moved).
19+
- This may require Bellman-Ford (for negative edge weights), because
20+
it's possible that snapping a vertex could actually improve the
21+
tet that it's a part of (our distance-minimizing algorithm
22+
assumes that moving a vertex will always make the tet worse).
23+
24+
- Improve mesh data structure efficiency
25+
- ie: adjacency list for triangle mesh, O(1) neighbor lookup, improve
26+
efficiency of graph search in match_features
27+
- Efficient TriMesh class created (half-edge data structures),
28+
but it isn't applicable to the mesh we've been using that
29+
indexes into the vertices of a TetMesh.
30+
31+
32+
Less important stuff:
33+
- Better tet-mesh data structures
34+
- More efficient traversal of edges, triangles.
35+
36+
- Tet Quality measures
37+
- Design pattern for plugging in arbitrary quality measure?
38+
39+
- FeatureSet::consolidate()
40+
41+
- Allow topology changes when matching features.
42+
- If unable to find path between two vertices separated by two boundary
43+
triangles, do an "edge split" or "edge flip" on the edge separating
44+
them.
45+
46+
- Curvature for automatic feature detection to detect feature points.
47+
48+
- Additional misc optimizations
49+
50+
- Handle more mesh file formats
51+
- .OFF (input, triangles)
52+
- .ELE (output, tets)
53+

0 commit comments

Comments
 (0)