luv

Workshop wiki

mesh-compression.lisp

luft/mesh-compression.lisp

system luft · 9 definitions · on GitHub

in-package#:luft
defun%coplanar-group-loops
triangles

Return oriented boundary loops, or NIL when the union is not simple.

let
edges
make-hash-table:test#'equal
dolist
triangletriangles
destructuring-bind
maskabc
triangle
declare
ignoremask
dolist
edge
list
listab
listbc
listca
let
if
gethashkeyedges
remhashkeyedges
setf
gethashkeyedges
edge
let
next
make-hash-table:test#'equal
incoming
make-hash-table:test#'equal
loopforedgebeingthehash-valuesofedgesdo
destructuring-bind
startend
edge
when
gethashstartnext
return-from%coplanar-group-loopsnil
setf
gethashstartnext
end
incf
gethashendincoming0
loopforstartbeingthehash-keysofnextunless
=1
gethashstartincoming0
do
return-from%coplanar-group-loopsnil
let
loopsnil
loopwhile
plusp
hash-table-countnext
do
let*
start
sort
loopforpointbeingthehash-keysofnextcollectpoint
#'%point-order<
start
firststart
pointstart
loopnil
loopdo
pushpointloop
multiple-value-bind
followingpresent-p
gethashpointnext
unlesspresent-p
return-from%coplanar-group-loopsnil
remhashpointnext
setfpointfollowing
until
equalpointstart
push
nreverseloop
loops
nreverseloops
defun%point-in-oriented-triangle-p
pointabcnormal
and
not
memberpoint
listabc
:test#'equal
defun%triangulate-coplanar-loop
loopnormal

Ear-clip one positively oriented simple integer polygon.

Retain collinear boundary vertices: another coplanar attribute group or differently oriented plane may meet there. Removing such a vertex would preserve the continuous surface but introduce a topological T-junction.

let
pointsloop
trianglesnil
when
<
lengthpoints
3
loopwhile
>
lengthpoints
3
do
let
ear-indexnil
count
lengthpoints
dotimes
indexcount
let
a
nth
mod
1-index
count
points
b
nthindexpoints
c
nth
mod
1+index
count
points
when
and
notany
lambda
point
points
setfear-indexindex
unlessear-index
let*
count
lengthpoints
a
nth
mod
1-ear-index
count
points
b
nthear-indexpoints
c
nth
mod
1+ear-index
count
points
push
listabc
triangles
setfpoints
loopforpointinpointsforindexfrom0unless
=indexear-index
collectpoint
pushpointstriangles
nreversetriangles
defun%emit-global-triangle
builderkindstockambientmasknormaltriangle
destructuring-bind
abc
triangle
let*
minimums
loopforaxisbelow3collect
min
nthaxisa
nthaxisb
nthaxisc
base
mapcar
lambda
coordinate
minimums
origin
mapcar
lambda
coordinate
base
scratch
surface-mesh-builder-vertex-scratchbuilder
%scratch-trianglescratch0
ecasekind
:face0
:band1
:junction2
mask
-
firsta
firstorigin
-
thirda
thirdorigin
-
firstb
firstorigin
-
thirdb
thirdorigin
-
firstc
firstorigin
-
thirdc
thirdorigin
firstnormal
secondnormal
thirdnormal
%emit-instancebuilderkind
firstbase
secondbase
thirdbase
stockambient3
defunsurface-mesh-with-triangle-ink
mesh

Return mesh's exact triangles with every primitive edge marked visible.

The geometry, stock, ambient value, primitive class, and winding are retained. Only the three construction-mask bits change. This diagnostic realization exposes connectivity that the ordinary semantic edge mask intentionally hides; it must not be substituted for the production mesh outside topology captures.

check-typemeshsurface-mesh
let
builder
%make-surface-mesh-builder
surface-mesh-domainmesh
surface-mesh-bevel-widthmesh
setf
surface-mesh-builder-singular-star-countbuilder
surface-mesh-singular-star-countmesh
%map-surface-mesh-triangle-records
lambda
kindstockambientmasknormalabc
declare
ignoremask
%emit-global-trianglebuilderkindstockambient#b111normal
listabc
mesh
defunsurface-mesh-split-neighborhood
meshsplit

Return only the triangles incident to the three points in split.

split is (LEFT MIDDLE RIGHT), as reported in the :CANDIDATE-SPLITS bevel diagnostic. A triangle is retained when two or more of its vertices are split points, so the result is the smallest actual mesh patch that contrasts one long edge with its two short neighbours. Every retained edge is marked visible; no vertex or triangle geometry is otherwise changed. This is the executable closeup used by the mixed-bevel degeneracy atlas. #WSEK3C

check-typemeshsurface-mesh
unless
and
listpsplit
=3
lengthsplit
error"A mesh split neighborhood needs (LEFT MIDDLE RIGHT), not ~S."split
let
builder
%make-surface-mesh-builder
surface-mesh-domainmesh
surface-mesh-bevel-widthmesh
%map-surface-mesh-triangle-records
lambda
kindstockambientmasknormalabc
declare
ignoremask
when
>=
count-if
lambda
point
memberpointsplit:test#'equal
listabc
2
%emit-global-trianglebuilderkindstockambient#b111normal
listabc
mesh
defun%coplanar-group-key<
leftright
flet
numeric-key
key
destructuring-bind
kindstockambientnormalplane
key
list
ecasekind
:face0
:band1
:junction2
stockambient
firstnormal
secondnormal
thirdnormal
plane
loopforlin
numeric-keyleft
forrin
numeric-keyright
when
/=lr
return
<lr
finally
defun%coplanar-merged-surface-mesh
mesh

Dissolve only interior edges between exactly coplanar equal-attribute faces.

The output has the same points, oriented planes, stocks, ambient values, silhouette, and depth as mesh. Groups with a non-simple boundary retain their original triangles, making the unmerged medial mesh a local rebuild oracle.

let
groups
make-hash-table:test#'equal
builder
%make-surface-mesh-builder
surface-mesh-domainmesh
surface-mesh-bevel-widthmesh
%map-surface-mesh-triangle-records
lambda
kindstockambientmasknormalabc
let
key
listkindstockambientnormal
%point-dotnormala
push
listmaskabc
gethashkeygroups
mesh
dolist
key
sort
loopforkeybeingthehash-keysofgroupscollectkey
#'%coplanar-group-key<
let
triangles
gethashkeygroups
destructuring-bind
kindstockambientnormalplane
key
declare
ignoreplane
let
loops
mergednil
boundary
make-hash-table:test#'equal
whenloops
dolist
looploops
loopforpointonloopfora=
firstpoint
forb=
or
secondpoint
firstloop
do
setf
gethashboundary
t
setfmerged
loopforloopinloopswhen
plusp
loopforpointonloopfora=
firstpoint
forb=
or
secondpoint
firstloop
sum
appendelsedo
setfloopsnil
if
andloopsmerged
dolist
trianglemerged
destructuring-bind
abc
triangle
let
mask
logior
if
gethashboundary
#b0010
if
gethashboundary
#b0100
if
gethashboundary
#b1000
%emit-global-trianglebuilderkindstockambientmasknormaltriangle
dolist
triangletriangles
%emit-global-trianglebuilderkindstockambient
firsttriangle
normal
resttriangle
setf
surface-mesh-builder-singular-star-countbuilder
surface-mesh-singular-star-countmesh
defuncoplanar-compressed-surface-mesh
mesh

Return mesh with only exact coplanar interior edges dissolved.

This is an explicit cold compression/diagnostic transform, never an alternate mode of mesh-chunk or the variable-width topology producer. mesh is not modified; groups whose boundary is not simple retain their original triangles.

check-typemeshsurface-mesh