luv

Workshop wiki

mesh-variation-plan.lisp

luft/mesh-variation-plan.lisp

system luft · 2 definitions · on GitHub

in-package#:luft

A transition plan is the small, owner-independent result of inspecting the complete witness closure. Emission consumes it without rediscovering collapse neighborhoods or weakening the canonical owner boundary.

defstruct
%bevel-transition-plan
:constructor%make-bevel-transition-plan
repair-splitsrepair-source-filtercandidate-splitscollapsed-triangle-countcontext-collapsed-triangle-countunmatched-edge-countresidual-edge-countrepair-point-count
repair-splitsnil:typehash-table:read-onlyt
repair-source-filternil:read-onlyt
candidate-splitsnil:typehash-table:read-onlyt
collapsed-triangle-count0:typefixnum:read-onlyt
context-collapsed-triangle-count0:typefixnum:read-onlyt
unmatched-edge-count0:typefixnum:read-onlyt
residual-edge-count0:typefixnum:read-onlyt
repair-point-count0:typefixnum:read-onlyt
defun%plan-variable-bevel-transitions
fieldowner-witnessesoutput-witnessesoutput-setrealize-setlive-triangle-counts-by-ownerpackingcontract-t-junctions-p

Discover and prove the complete local contraction plan for one cohort.

Only a three-distinct-point collinear collapse can create the long-edge / two-short-edge mismatch. Count that exact local edge neighborhood, not every edge in the otherwise closed witness.

let
all-candidate-splits
make-hash-table:test#'eql
relevant-candidate-edges
make-hash-table:test#'eql
candidate-splits
make-hash-table:test#'eql
queried-edge-counts
make-hash-table:test#'eql
repair-splits
make-hash-table:test#'eql
queried-source-filternil
repair-source-filternil
collapsed-triangle-count0
context-collapsed-triangle-count0
%with-bevel-site-width-field
site-width
field
labels
spatial-edge-key
lxlylzrxryrz
nth-value0
%pack-spatial-edgepackinglxlylzrxryrz
record-candidate
ownerlxlylzrxryrzmiddle
let
edge
spatial-edge-keylxlylzrxryrz
pushnewmiddle
gethashedgeall-candidate-splits
:test#'=
when
nth-value1
gethashowneroutput-set
setf
gethashedgerelevant-candidate-edges
t
discover-transition
ownerkindaxayazbxbybzcxcycz
%with-transformed-bevel-triangle
taxtaytaztbxtbytbztcxtcytcz
site-widthaxayazbxbybzcxcycz
multiple-value-bind
nxnynz
%triangle-cross-scalarstaxtaytaztbxtbytbztcxtcytcz
if
and
zeropnx
zeropny
zeropnz
progn
incfcontext-collapsed-triangle-count
when
nth-value1
gethashowneroutput-set
incfcollapsed-triangle-count
unless
or
and
=taxtbx
=taytby
=taztbz
and
=tbxtcx
=tbytcy
=tbztcz
and
=tcxtax
=tcytay
=tcztaz
let*

Match the reference reduction's later-edge tie preference, though a collinear interior point gives the long edge a strict maximum.

if
>abbc
if
>abca
record-candidateownertaxtaytaztbxtbytbzpc
record-candidateownertcxtcytcztaxtaytazpb
if
>bcca
record-candidateownertbxtbytbztcxtcytczpa
record-candidateownertcxtcytcztaxtaytazpb
when
nth-value1
gethashownerrealize-set
incf
aref
gethashownerlive-triangle-counts-by-owner
ecasekind
:face0
:band1
:junction2
mark-candidate-edge
lxlylzrxryrz
let
edge
spatial-edge-keylxlylzrxryrz
when
nth-value1
gethashedgeall-candidate-splits
setf
gethashedgerelevant-candidate-edges
t
mark-output-candidate-edges
axayazbxbybzcxcycz
%with-transformed-bevel-triangle
taxtaytaztbxtbytbztcxtcytcz
site-widthaxayazbxbybzcxcycz
multiple-value-bind
nxnynz
%triangle-cross-scalarstaxtaytaztbxtbytbztcxtcytcz
unless
and
zeropnx
zeropny
zeropnz
mark-candidate-edgetaxtaytaztbxtbytbz
mark-candidate-edgetbxtbytbztcxtcytcz
mark-candidate-edgetcxtcytcztaxtaytaz
count-queried-edge
lxlylzrxryrz
let
key
spatial-edge-keylxlylzrxryrz
multiple-value-bind
countpresent-p
gethashkeyqueried-edge-counts
whenpresent-p
setf
gethashkeyqueried-edge-counts
1+count
scan-queried-transition
axayazbxbybzcxcycz
%with-transformed-bevel-triangle
taxtaytaztbxtbytbztcxtcytcz
site-widthaxayazbxbybzcxcycz
multiple-value-bind
nxnynz
%triangle-cross-scalarstaxtaytaztbxtbytbztcxtcytcz
unless
and
zeropnx
zeropny
zeropnz
count-queried-edgetaxtaytaztbxtbytbz
count-queried-edgetbxtbytbztcxtcytcz
count-queried-edgetcxtcytcztaxtaytaz
declare
inlinespatial-edge-keypacked-point-edge-keyrecord-candidatemark-candidate-edgecount-queried-edge
dolist
owner-witnessowner-witnesses
let
owner
carowner-witness
witness
cdrowner-witness
%do-surface-mesh-triangle-scalars
witnesskindstockambientmaskaxayazbxbybzcxcycz
declare
ignorestockambientmask
discover-transitionownerkindaxayazbxbybzcxcycz

A guard-owned collapse can require a repair child in an output mesh. Mark candidates whose surviving long edge occurs on an output-owned source triangle as well as candidates created by output collapses.

dolist
owner-witnessoutput-witnesses
let
witness
cdrowner-witness
%do-surface-mesh-triangle-scalars
witnesskindstockambientmaskaxayazbxbybzcxcycz
declare
ignorekindstockambientmask
mark-output-candidate-edgesaxayazbxbybzcxcycz
maphash
lambda
edgepoints
when
nth-value1
gethashedgerelevant-candidate-edges
setf
gethashedgecandidate-splits
points
all-candidate-splits
setfqueried-edge-counts
make-hash-table:test#'eql:size
max16
*3
hash-table-countcandidate-splits
maphash
lambda
edgepoints
multiple-value-bind
leftright
let*
left-packed
%pack-global-mesh-point
firstleft
secondleft
thirdleft
right-packed
%pack-global-mesh-point
firstright
secondright
thirdright
points
sortpoints#'<:key
lambda
point
setf
gethashedgecandidate-splits
points
gethashedgequeried-edge-counts
0
loopwithprevious=left-packedforpointinpointsdo
setf
gethash
packed-point-edge-keypreviouspoint
queried-edge-counts
0
previouspoint
finally
setf
gethash
packed-point-edge-keypreviousright-packed
queried-edge-counts
0
candidate-splits
setfqueried-source-filter
%make-source-anchor-filterpackingqueried-edge-counts
whenqueried-source-filter
dolist
owner-witnessowner-witnesses
let
witness
cdrowner-witness
%do-surface-mesh-triangle-scalars
witnesskindstockambientmaskaxayazbxbybzcxcycz
declare
ignorekindstockambientmask
when
%triangle-touches-source-anchor-filter-pqueried-source-filteraxayazbxbybzcxcycz
scan-queried-transitionaxayazbxbybzcxcycz
let
unmatched-edge-count
loopforcountbeingthehash-valuesofqueried-edge-countscount
not
or
zeropcount
=count2
whencontract-t-junctions-p
maphash
lambda
edgepoints
when
=1
gethashedgequeried-edge-counts0
multiple-value-bind
leftright
let
left
%pack-global-mesh-point
firstleft
secondleft
thirdleft
right
%pack-global-mesh-point
firstright
secondright
thirdright
when
loopwithprevious=leftforpointinpointsalways
=1
gethash
packed-point-edge-keypreviouspoint
queried-edge-counts0
do
setfpreviouspoint
finally
return
=1
gethash
packed-point-edge-keypreviousright
queried-edge-counts0
setf
gethashedgerepair-splits
points
candidate-splits
setfrepair-source-filter
%make-source-anchor-filterpackingrepair-splits

Prove that the selected contractions account for the entire mismatch before changing any triangles. A new failure mode must become explicit rather than rendering another hairline crack.

maphash
lambda
edgepoints
decf
gethashedgequeried-edge-counts
multiple-value-bind
leftright
let
left
%pack-global-mesh-point
firstleft
secondleft
thirdleft
right
%pack-global-mesh-point
firstright
secondright
thirdright
loopwithprevious=leftforpointinpointsdo
incf
gethash
packed-point-edge-keypreviouspoint
queried-edge-counts0
setfpreviouspoint
finally
incf
gethash
packed-point-edge-keypreviousright
queried-edge-counts0
repair-splits
let
residual-edge-count
loopforcountbeingthehash-valuesofqueried-edge-countscount
not
or
zeropcount
=count2
when
andcontract-t-junctions-p
pluspresidual-edge-count
error"Site-local bevel contraction left ~D of ~D unmatched edges after ~D repairs."residual-edge-countunmatched-edge-count
hash-table-countrepair-splits
%make-bevel-transition-planrepair-splitsrepair-source-filtercandidate-splitscollapsed-triangle-countcontext-collapsed-triangle-countunmatched-edge-countresidual-edge-count
loopforpointsbeingthehash-valuesofrepair-splitssum
lengthpoints