Large Mesh Simplificationusing Processing Sequences
Martin IsenburgUNC
Chapel Hill
Peter LindstromLLNL
Livermore
Stefan GumholdGRIS
Tubingen
Jack SnoeyinkUNC
Chapel Hill
Overview
• Motivation
• Background
• Processing Sequences
• Adapted Simplification Schemes– OOCS
– Wu & Kobbelt
• Conclusion
Motivation
Large Meshes
3D scans isosurfaces
Large Meshes
3D scans isosurfaces
PPM isosurface
• 235 million vertices
• 469 million triangles
• 235 million rtices
• million trianglesover
8 Gigabyte !
hampers:• distributing / loading• rendering• processing
• in-core algorithms of choice:– Qslim
– Rsimp
Mesh Simplification
• alternative: processing sequence
[Garland & Heckbert ’97]
[Brodsky & Watson ’00]
require~ 200 bytesper vertex
• current out-of-core approaches:1. piece by piece
2. external memory
3. polygon soup [Lindstrom ’00]
[Hoppe ’98]
[Cignoni et al. ’03]
Background
Related Work
• Large Mesh Processing– Simplification
– Compression
– Visualization Systems
• Main Techniques 1. Mesh Cutting
2. Online Processing
3. Batch Processing
• cut mesh into small pieces
• process each separately
• special treatment for cuts
• stitch result back together
1. Mesh Cutting
figure courtesy of Hugues Hoppe
2. Online Processing
• external memory datastructures
• “random” mesh access
figure courtesy of Paolo Cignoni
3. Batch Processing (1)
• polygon soup
• single scan over stream ofde-referenced triangles
• no explicit connectivity
[Lindstrom ’00]
3. Batch Processing (2)
• polygon soup
• single scan over stream ofde-referenced triangles
• no explicit connectivity
(coherent)
reconstruct
figure courtesy of Jianhua Wu and Leif Kobbelt
[Wu & Kobbelt ’03]
Sequenced Processing
• coherent triangle orderinginterleaved with vertices
• small footprint streaming
• finalization of vertices
[Isenburg & Gumhold ’03]
Quadric Error Matrices
• accumulate error
• vertex placement
• sum of squareddistances of point to set of planes
• quadric error:
figure courtesy of Michael Garland
[Garland & Heckbert ’97]
Q =q00 q01 q02 q03
q10 q11 q12 q13
q20 q21 q22 q23
q30 q31 q32 q33
vTQv
Processing Sequences
A little history …
• Compressor– region growing
A little history …
• Compressor– region growing
• Out-of-Core Mesh– transparent
– caching clusters
A little history …
• Compressor– region growing
• Out-of-Core Mesh– transparent
– caching clusters
• Compact Format– small footprint
– streaming
A little history …
• Compressor– region growing
• Out-of-Core Mesh– transparent
– caching clusters
• Compact Format– small footprint
– streaming
A little history …
• Compressor– region growing
• Out-of-Core Mesh– transparent
– caching clusters
• Compact Format– small footprint
– streaming
• interleaved ordering of triangles and vertices that “grows regions”
processingboundary
Processing Sequences
border edges
Q7
Q1
Q4
• available information:– first & last use of edges & vertices
– surface border
• maintaindata alongboundary
unprocessed region
Abstractions
• boundary-based– one boundary
– process immediately
processed region
waiting area
processingboundary
processed region
unprocessed region
Abstractions
• boundary-based– one boundary
– process immediately
• buffer-based– two boundaries
– process in buffer
– read to fill
– write to empty
in-corebuffer
output boundary
input boundary
processed region
unprocessed region
processingboundary
waiting area
OOCS
OOCS
• stream in polygon soup– triangle after triangle
• vertex clustering– one quadric per grid cell
• output sensitive– store all quadrics
• no border info – tangential
term added
OOCS
Q
Q
input output
OOCS
Q
Q
Q
Q
input output
OOCS
Q
Q
Q
Q
input output
OOCS
Q
Q
Q Q
Q
input output
OOCS
Q Q
Q Q Q
Q
Q
input output
Q
OOCS
Q Q
QQ Q Q Q
Q Q
Q
Q Q Q
Q
Q
Q
Q
Q
Q
input output
OOCS
Q Q
Q
Q
Q
QQ Q Q Q
Q Q
Q
Q
Q Q
Q Q
Q
Q
Q
QQQ
Q Q Q
QQQQ
Q
QQQ
Q Q
Q
input output
OOCS
Q Q
Q
Q
Q
QQ Q Q Q
Q Q
Q
Q
Q Q
Q Q
Q
Q
Q
QQQ
Q Q Q
QQQQ
Q
QQQ
Q Q
Q
input output
OOCS
Q Q
Q
Q
Q
QQ Q Q Q
Q Q
Q
Q
Q Q
Q Q
Q
Q
Q
QQQ
Q Q Q
QQQQ
Q
QQQ
Q Q
Q
input output
OOCS using PS
• fewer artifacts– do not collapse multiple
layers into single vertex
– improved surface boundaries
• streaming output
OOCS using PS
• memory insensitive– maintain much fewer quadrics
processedregion
unprocessedregion
Q7
7
Q55
55
OOCS using PS (detail)
Q33
Q4
4
4
processedregion
unprocessedregion
Q55
Q4
Q7
7
4
4
Q3
5
3
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q4
Q7
7
4
4
5
Q3
turns into vertex quadric
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q4
Q7
7
4
4
5
Q8
8
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q4
Q7
7
4
5
Q8
8
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q4
Q7
7
5
Q8
8
quadric turns into vertex
8
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q7
7
5
Q8
88
Q9
9
OOCS using PS (detail)
processedregion
unprocessedregion
Q55
Q7
7
Q8
88
Q9
9quadricmerge
OOCS using PS (detail)
OOCS using PSinput output
OOCS using PS
Q
Q
Q
Q
outputinput
OOCS using PS
Q
Q Q
Q Q
Q
outputinput
Q Q
OOCS using PS
Q
Q
Q
Q
Q Q
Q
Q
Q
outputinput
Q Q
OOCS using PS
Q
Q
Q
Q
Q
outputinput
Q
Q Q
Q Q
Q
QQ Q
Q
OOCS using PS
Q
Q
Q
Q
outputinput
Q
Q
Q
Q
Q
Q
Q Q
Q Q
Q
Q Q
Q
Q
Q
Q
OOCS using PS
Q
Q
Q
outputinput
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q Q
Q Q
Q
Q Q
Q
Q
Q
OOCS using PS
QQQ
Q
Q
Q
outputinput
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q Q
Q Q
Q
Q Q
Q
Q
Q
Q
OOCS using PS
Q
Q
Q
outputinput
QQQ
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q Q
Q Q
Q
Q Q
Q
Q
Q
Q
Q
OOCS using PSoutputinput
QQQ
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q Q
Q Q
Q
Q Q
Q
Q
Q
Q
Q
Q
Q
Q
Improved Mesh QualityOOCS-PS
OOCS
vertices: 33,053
non-manifoldvertices: 3,366
vertices: 35,134
non-manifoldvertices: 897
Lower Memory Requirements
373 million vertices
OOCSmemory:
3,282 MBtime:
67 minOOCS-PSmemory:
121 MBtime:
83 min23 million vertices
Wu & Kobbelt
Wu & Kobbelt
• stream coherent soup into buffer• reconstruct connectivity
– hash on vertex data– finalize complete stars
inputboundary
a aa a
a
aaa
a
accumulating
c c
collapsible
• randomized edge collapse – one quadric per vertex– accumulating collapsible
• randomized streaming output
Wu & Kobbelt
ca
a
a
a
a
a
a
input output
Wu & Kobbelt
c
cc
c
c
c
cc
c
a
a
a
aa
aa
a
a
a
a
a
aa
a
a aa
aa
a
a
a
a
a
a
a
input output
Wu & Kobbelt
c
cc
cc
aa
a a
c
a
a
a
aa
a
c
c
c
a
a
a
aa
a
a
aa
a
a
a
c
c
ca
a
a
a
a
a
aa
a
aa
a
a
a
a
a
a
c
c
c
outputinput
Wu & Kobbelt
c
c
c
c
c
aaaa
a
a
a
aa
a c
c
c
a
a
a
aa
a a
aa
a
a
a
cc
ca
a
a
a
a
a
a
a
a
a a
a
a
a
a
a
a
c
ca
aa
a
a
c
c
c
c
cc
cc
c
aa
a
a
c
cc
c
a
a
outputinput
Wu & Kobbelt
c
c
c
c
c
aaaa
a
a
a
a
a
a
c
c
a
a
a
a a
a a
aa
a
aa
c
ca
a
a
aa
a
a
a a
a
a
a
a
a
c
c
aa
a
a
a
c
c
c
cc
aa
a
a
c
c
c
c
a
a
aa
aa
aa
c
c
c
c
c c
c
c
c
c
c
c
cc
c
c
c
c c
outputinput
Wu & Kobbelt
c
aaaa
a
aa
a
a
a
a
aa
a
a
a
a
a
a
a
aa
a
a
a a
a
a
a
a
a
c
aa a
a
a
c
aa
a
a
aa
a
a
a
a
c
c
c c
c
c
c
caa
a
a
aa
a a
a
aa
a
a a a a
a
a
a
a
a
ac
c
c
c
c c
c
c
c
c
c
c c
outputinput
Wu & Kobbelt
aaaa
a
aa
a
a
a
a
aa
a
a
a
a
a
a
a
aa
a
aa a
a
a
a
a
a
aa a
a
a aa
a
a
a
a
a
a
a
a
c
c
a
a
a
a
aa
a
a
a
a
a
a
a a a a
a
a a
a
a
ac
c
c
aaa
aa
a
aa
aa
aa
aa
a
c
c
c c
cc
c
c
c
cc
outputinput
Wu & Kobbelt
aaaa
a
aa
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
aa a
a
a
a
a
a
a a
a
a aa
a
a
a
a
a
a
a
c
a aa
a
a
a
a
a
a
a
a
a
a a a a
a
a
a
aa
aa
a
aa a
a
a
aaa
a
a
a
a
c
c
a
a
a
a
cc c
ccc
cc
c
ac
a
outputinput
Wu & Kobbelt
aaaa
a
aa
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
aa a
a
a
a
a
a
a a
a
a aa
a
a
aa
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a a a a
a
a
a
aa
a
a
a
a a a
a
a
a
a
aa
a
a
a
a
aaa
a
c
cc
cc
a aa
a
c
outputinput
border
Wu & Kobbelt
aaaa
a
aa
a
a
a
a
a
a
a
a
a
a
a
a
a
a
aa a
a
a
a
a
a
a a
a
a aa
a
a
a
a
a
a
aa
a
a
a
a
a
a
a
a
a a a a
a
a
a
aa
a
aa a a
a
a
aa
a
a
a
aaa
a
aa
a
aa
a
a
aa
a
c
c
c
cc
outputinput
Wu & Kobbelt
c
c
c
c
c
c
c
c
c
c
c
c
cc c
c
c
c
c
c
c
c cc
c
c
c
c
cc
c
c
c
c
c
c
c
c c c c
c
c
c
c
c
ccc
cccc
cc
c
c
c
c c c
c
c
c
c
c
c
cc c
c
c
cc
c
c
cc
c
cc
c
c
cc
c
c
c
c
cc
outputinput
Wu & Kobbelt
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c c
cc
c
cc
c
c
c
c
c c
c
c
cc
c
c
c
c
cc
c
c
c
c
c
outputinput
Wu & Kobbelt
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
cc
c
c
c
c
c
c
c
outputinput
Wu & Kobbeltoutputinput
Wu & Kobbelt using PS
Wu & Kobbelt using PS
• less fragmentation of buffer– processing sequence input / output
– more collapsible edges
• immediate boundary simplification– mesh borders known early
– truly “streaming” output
• faster connectivity reconstruction– indexed input / API support
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
a
a
a
a
a
a
a
accumulating
c
cc
c
c
c
c
collapsible
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
c
cc
c
c
c
c
collapsible
a
a
a
a
a
a
a
accumulating
c
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
c
cc
c
c
c
c
collapsible
a
a
a
a
a
a
a
a
accumulating
c
c
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
cc
c
c
c
collapsible
a
a
a
a
a
a
a
a
accumulating
c
c
c
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
cc
c
c
c
collapsible
a
a
a
a
a
a
a
a
accumulating
c
c
c
Wu & Kobbelt using PS (detail)
unprocessedregion
processedregion
inputboundary
outputboundary
in-coretrianglebuffer
cc
c
c
c
collapsible
a
a
a
a
a
a
a
a
accumulating
c
c
Wu & Kobbelt using PSinput output
Wu & Kobbelt using PS
a
c
aaa
a
aaaa
a
a
c
cc
outputinput
Wu & Kobbelt using PS
a
a a aaaa
a
a
aaaaaa
a
a
a
c c
cc
c
cc
c
c
c c c
c
outputinput
Wu & Kobbelt using PS
aa a
a a
a
aa
a
a
a
aa
aa
aaa
a
aaa
a
a
a
aa
c
cc
c
c
c
cc
c
c
c
cc
cc
c
c
cc
ccc
c
c
cc
outputinput
Wu & Kobbelt using PS
aa
a
aaa
a a
aa
a a
aa
a
a
a
a
a
aa aa
a
c
c
c
c c
c
c
c
c
c
c
ccc
ccc
c
c
c
c
c
c
c
c
c
c
c
c
cc
cc
c
c
cc
outputinput
Wu & Kobbelt using PS
a a
a
a
a
aa
a
aa
a
a
a
a
c
c cc
ccc
c
c
c
c
cc
c
c
c
c
cc
cc
c c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
input output
Wu & Kobbelt using PS
aa
a
aa
a
a
a
a
a
aa
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
cc
c
c
c
c
c
c
c
c
c
c
c
c
input output
Wu & Kobbelt using PS
a
a
aa a
a
a a
a
a
aa
c
c
c
c
c
c
c
c
c
c
c
ac
c
c
c
c
c
c
c
c c
c
c
c
c
c
c
input output
Wu & Kobbelt using PS
a
a
a
a
a
a
a
a
ac
a
c
c
c
c
c
c
c
c c
c
c
c
c
a
c
c
c
c
cc
c
cc
cc
c
c
c
c
c
c
input output
Wu & Kobbelt using PS
c c
cc
c
cc
cc
c
cc
cc
c
c
c
input output
Wu & Kobbelt using PSinput output
Conclusion&
Current Work
Summary
• processing sequences– efficient large mesh access
– streaming input and output
– abstractions: • boundary-based• buffer-based
• adapted simplification algorithms:– OOCS
– Wu & Kobbelt
• length of processing boundary– possible
– traversal is optimized for lowest bit-rate change heuristic
Issues
O( n ) [Bar-Yehuda & Gotsman ‘96]
• external memory mesh to createprocessing sequences …?– expensive to build & use
– defeats purpose …
Generating PS
• on-the-fly
• input: “streaming mesh”
v 1.32 0.12 0.23v 1.43 0.23 0.92v 0.91 0.15 0.62f 1 2 3done 2 v 0.72 0.34 0.35f 4 1 3done 1 ⋮ ⋮ ⋮ ⋮
verticesfinalized
(not used bysubsequenttriangles)
• extend to volume meshes
• promote– provide API
• create / improve– lower processing boundary length
Current Work
• compress– encode on-the-fly
Thank You.
v0
v1
v2
fill
Growing Operations
v0 v1
v2
end
v0 v1
v2
start
v0v1
v2
join
add
v0 v1
v2
processingboundary
read nexttriangle
info aboutcurrenttriangle
optionalmaintainingof user data
Prototype of PS API int open(const char* file_name);int read_triangle();void close();
int t_idx[3];float* t_pos_f[3];int t_vflag[3];int t_eflag[3];
void set_edata( void* data, int i );void set_vdata( void* data, int i );void* get_edata( int i );void* get_vdata( int i );
Example (1)
v0 v1
v2
eflag[0] = PS_FIRST eflag[1] = PS_FIRST eflag[2] = PS_FIRST
vflag[0] = PS_FIRSTvflag[1] = PS_FIRSTvflag[2] = PS_FIRST
v0 v1
v2
eflag[0] = PS_FIRST eflag[1] = PS_FIRST | PS_LAST eflag[2] = PS_FIRST | PS_LAST
vflag[0] = PS_FIRSTvflag[1] = PS_FIRST | PS_LASTvflag[2] = PS_FIRST
borderedge
enteringedge
borderedge
e0
e1
e2
start
start
enteringedge
leavingedges
borderedge
enteringedge
leaving edge
v0 v1
v2
add
Example (2)
eflag[0] = PS_LASTeflag[1] = PS_FIRST | PS_LASTeflag[2] = PS_FIRST
vflag[0] = 0vflag[1] = 0vflag[2] = PS_FIRST
eflag[0] = PS_LAST eflag[1] = PS_FIRSTeflag[2] = PS_LAST
vflag[0] = PS_LASTvflag[1] = 0vflag[2] = 0
fill
v0
v1
v2
Example (3)
eflag[0] = PS_LASTeflag[1] = PS_LASTeflag[2] = PS_LAST
vflag[0] = PS_LASTvflag[1] = PS_LASTvflag[2] = PS_LAST
eflag[0] = PS_LAST eflag[1] = PS_LAST eflag[2] = PS_LAST
vflag[0] = PS_LASTvflag[1] = 0vflag[2] = PS_LAST
leaving
edges
v0 v1
v2
v0 v1
v2
end
end
Computing Smooth Normalsps.open ( “bunny.sma” );while ( ps.read_triangle() ) tmp = compute ( ps.t_pos[0], ps.t_pos[1], ps.t_pos[2] ); for ( i = 0; i < 3; i++ ) if ( ps.vflag[i] & PS_FIRST ) n = new Normal (); ps.set_vdata ( n, i ); else n = ps.get_vdata ( i ); add ( n, tmp ); if ( ps.vflag[i] & PS_LAST ) normalize ( n ); do something delete n;
ps.close ();