luv

Workshop wiki

mesh-realization.lisp

luft/mesh-realization.lisp

system luft · 19 definitions · on GitHub

in-package#:luft

--------------------------------------------------------------------------- Exact coplanar compression

defun%point-order<
leftright
loopforlinleftforrinrightwhen
/=lr
return
<lr
finally
defun%ordered-point-edge
leftright
if
%point-order<leftright
listleftright
listrightleft
defun%point-cross
abc
let
ux
-
firstb
firsta
uz
-
thirdb
thirda
vx
-
firstc
firsta
vz
-
thirdc
thirda
list
-
*uyvz
*uzvy
-
*uzvx
*uxvz
-
*uxvy
*uyvx
defun%point-dot
leftright
+
*
firstleft
firstright
*
secondleft
secondright
*
thirdleft
thirdright
defun%primitive-plane-normal
abc
let*
cross
divisor
reduce#'gcdcross:key#'abs
unless
pluspdivisor
error"Degenerate triangle in coplanar compression: ~S ~S ~S."abc
mapcar
lambda
coordinate
/coordinatedivisor
cross
defun%map-surface-mesh-triangle-records

Call function with kind, stock, ambient, mask, normal, and three points.

let
templates
surface-mesh-template-vertex-wordsmesh
ranges
surface-mesh-template-rangesmesh
labels
visit
wordskind
loopforoffsetfrom0below
lengthwords
by4forbase=
list
arefwordsoffset
arefwords
+offset1
arefwords
+offset2
formeta=
arefwords
+offset3
fortemplate-id=
ldb
byte160
meta
forstock=forambient=forstart=
arefranges
*2template-id
forcount=
arefranges
1+
*2template-id
do
loopforvertexfromstartbelow
+startcount
by3forattributes=fora=
pointbasevertex
forb=
pointbase
1+vertex
forc=
pointbase
+vertex2
fornormal=do
funcallfunctionkindstockambient
ldb
byte310
attributes
normalabc
visit
surface-mesh-face-instance-wordsmesh
:face
visit
surface-mesh-band-instance-wordsmesh
:band
visit
surface-mesh-fan-instance-wordsmesh
:junction

--------------------------------------------------------------------------- Sparse semantic attachment realization

defstruct
surface-attachment-frame
:constructor%make-surface-attachment-frame
originnormaltangentprimitive-kindsstocks
:copiernil

One authored face-chart point resolved against the finished surface.

ORIGIN is in renderer world units. NORMAL is the outward unit normal of the hit primitive, or the deterministic unit bisector of its normal cone when the chart point lies exactly on a crease. TANGENT is the authored face's first chart axis projected into that tangent plane. The primitive and stock lists retain the cold diagnostic provenance of every tied hit.

origin
:type
simple-arraysingle-float
3
:read-onlyt
normal
:type
simple-arraysingle-float
3
:read-onlyt
tangent
:type
simple-arraysingle-float
3
:read-onlyt
primitive-kindsnil:typelist:read-onlyt
stocksnil:typelist:read-onlyt
defun%surface-frame-axis-vector
ecaseaxis
:x'
1.0d00.0d00.0d0
:y'
0.0d01.0d00.0d0
:z'
0.0d00.0d01.0d0
defun%surface-frame-dot
leftright
+
*
firstleft
firstright
*
secondleft
secondright
*
thirdleft
thirdright
defun%surface-frame-scale
amountvector
mapcar
lambda
component
*amountcomponent
vector
defun%surface-frame+
&restvectors
loopforaxisbelow3collect
loopforvectorinvectorssum
nthaxisvector
defun%surface-frame-cross
leftright
list
-
*
secondleft
thirdright
*
thirdleft
secondright
-
*
thirdleft
firstright
*
firstleft
thirdright
-
*
firstleft
secondright
*
secondleft
firstright
defun%surface-frame-unit
vector
let
unless
>length1.0d-12
error"Cannot normalize the zero attachment-frame vector ~S."vector
defun%surface-frame-point-in-projected-triangle-p
pointabcu-axisv-axis

Test point in ABC after projection into the authored face chart.

labels
project
value
values
edge
axaybxbypxpy
-
*
-pxax
-byay
*
-pyay
-bxax
multiple-value-bind
pxpy
projectpoint
multiple-value-bind
axay
projecta
multiple-value-bind
bxby
projectb
multiple-value-bind
cxcy
projectc
let*
ab
edgeaxaybxbypxpy
bc
edgebxbycxcypxpy
ca
edgecxcyaxaypxpy
epsilon1.0d-8
negative-p
or
<ab
-epsilon
<bc
-epsilon
<ca
-epsilon
positive-p
or
>abepsilon
>bcepsilon
>caepsilon
not
andnegative-ppositive-p
defun%surface-frame-nearest-projected-triangle-point
chartabcu-axisv-axisauthored-normalprimitive-normaldenominator

Return the nearest chart-projected point of ABC and its squared distance.

When chart projects inside ABC, retain the original authored-normal ray intersection exactly. Otherwise the nearest point of the closed projected triangle lies on one of its three edges; lift that edge parameter back onto the actual three-dimensional primitive.

if
let
displacement
/
-
%surface-frame-dotprimitive-normala
%surface-frame-dotprimitive-normalchart
denominator
values
%surface-frame+chart
%surface-frame-scaledisplacementauthored-normal
0.0d0
let
chart-u
chart-v
best-pointnil
best-distance-squarednil
labels
visit-edge
startend
let*
edge-u
edge-v
length-squared
+
*edge-uedge-u
*edge-vedge-v
start-u
start-v
parameter
max0.0d0
min1.0d0
/
+
*
-chart-ustart-u
edge-u
*
-chart-vstart-v
edge-v
length-squared
delta-u
-chart-u
delta-v
-chart-v
distance-squared
+
*delta-udelta-u
*delta-vdelta-v
when
or
nullbest-distance-squared
<distance-squaredbest-distance-squared
and
=distance-squaredbest-distance-squared
%point-order<pointbest-point
setfbest-pointpointbest-distance-squareddistance-squared

A facing triangle has a nonzero chart projection, so at least two of these projected edges have positive length. Skip the possible zero-length edge defensively rather than dividing by zero.

dolist
edge
list
listab
listbc
listca
let*
start
firstedge
end
secondedge
du
dv
when
>
+
*dudu
*dvdv
1.0d-20
visit-edgestartend
unlessbest-point
error"Facing attachment triangle has no projected edge: ~S ~S ~S."abc
valuesbest-pointbest-distance-squared
defun%surface-frame-point-in-support-footprint-p
pointcenteru-axisv-axisepsilon

Test point in the authored face's inclusive one-cell footprint.

let*
half-cell
limit
+half-cellepsilon
u
%surface-frame-dotoffsetu-axis
v
%surface-frame-dotoffsetv-axis
and
<=
-limit
ulimit
<=
-limit
vlimit
defun%surface-frame-point-distance-squared
leftright
loopforlinleftforrinrightfordelta=
-lr
sum
*deltadelta
defun%surface-frame-candidate-relation
radius-squareddisplacementpointbest-radius-squaredbest-displacementbest-pointtie-epsilonradius-squared-tie-epsilonpoint-squared-tie-epsilon

Classify one admissible candidate against the current geometric optimum.

cond
or
nullbest-radius-squared
<radius-squared
-best-radius-squaredradius-squared-tie-epsilon
:replace
<=
abs
-radius-squaredbest-radius-squared
radius-squared-tie-epsilon
cond
>displacement
+best-displacementtie-epsilon
:replace
<=
abs
-displacementbest-displacement
tie-epsilon
cond
<=point-squared-tie-epsilon
:tie
%point-order<pointbest-point
:replace
t:ignore
t:ignore
t:ignore
defunresolve-surface-attachment-frame
meshesface&key
u0.0d0
v0.0d0

Resolve face chart coordinates U/V against finished meshes.

U and V are normalized logical-face coordinates in [-1,1]. The square chart is compacted radially onto |U|+|V|<=1: points already inside that diamond are unchanged, while logical corners map continuously onto the realized junction domain instead of casting through empty space beyond a chamfered corner.

For every facing finished triangle, the resolver finds the closest point in the authored face chart and lifts it onto that actual primitive. Candidates are ranked first by minimum tangential distance and then by outermost normal displacement. Thus any triangle under the old authored-normal ray has zero tangential distance and produces the exact old result; only a genuine ray miss moves tangentially onto the nearest finished face, band, transition triangle, or junction fan.

The finished surface of the authored support cell cannot lie outward of its cubical face or more than the mesh's maximum bevel width inward or tangentially away from the mapped chart point. It must also stay inside the exact one-cell support-face footprint. Enforcing that slab, radius, footprint, and outward facing cone is an ownership condition, not a global nearest-hit heuristic: parallel or neighboring surfaces elsewhere must never steal the attachment.

At a non-smooth point there is no unique differential normal. Rather than falling back to the cubical face, this function returns the normalized sum of the distinct tied primitive normals: a deterministic bisector of the actual surface normal cone.

unless
listpmeshes
setfmeshes
listmeshes
unlessmeshes
error"Attachment realization needs at least one finished surface mesh."
unless
every
lambda
mesh
typepmesh'surface-mesh
meshes
error"Attachment realization received a non-mesh member in ~S."meshes
unless
and
realpu
<=-1u1
realpv
<=-1v1
error"Attachment chart coordinates must lie in [-1,1], not (~S,~S)."uv
let
domain
surface-mesh-domain
firstmeshes
unless
every
lambda
mesh
eqdomain
surface-mesh-domainmesh
restmeshes
error"Attachment realization meshes do not share one world domain."
%require-facedomainface
multiple-value-bind
u-namev-name
multiple-value-bind
normal-xnormal-ynormal-z
let*
authored-normal
mapcar#'coerce
listnormal-xnormal-ynormal-z
make-list3:initial-element'double-float
v-axis
if
minusp
%surface-frame-dotauthored-normal
v-axis
center
loopforcoordinatein
list
site-xface
site-yface
site-zface
foraxis-numberbelow3collect
coerce
+
if
logbitpaxis-number
0
'double-float
chart-u
coerceu'double-float
chart-v
coercev'double-float
chart-scale
max1.0d0
+
abschart-u
abschart-v
chart
%surface-frame+center
%surface-frame-scale
*0.5d0+mesh-cell-size+
/chart-uchart-scale
u-axis
%surface-frame-scale
*0.5d0+mesh-cell-size+
/chart-vchart-scale
v-axis
best-radius-squarednil
best-displacementnil
best-pointnil
hitsnil
maximum-inset
reduce#'maxmeshes:key#'surface-mesh-bevel-width
tie-epsilon
*1.0d-7
max1maximum-inset
point-squared-tie-epsilon
*tie-epsilontie-epsilon
radius-squared-tie-epsilon
+
*2.0d0maximum-insettie-epsilon
point-squared-tie-epsilon
maximum-radius-squared
+
*maximum-insetmaximum-inset
radius-squared-tie-epsilon
dolist
meshmeshes
%map-surface-mesh-triangle-records
lambda
kindstockambientmaskprimitive-normalabc
declare
ignoreambientmask
let*
primitive-normal
mapcar
lambda
value
coercevalue'double-float
primitive-normal
denominator
%surface-frame-dotprimitive-normalauthored-normal
when
>denominator1.0d-10
multiple-value-bind
pointradius-squared
%surface-frame-nearest-projected-triangle-pointchartabcu-axisv-axisauthored-normalprimitive-normaldenominator
let
displacement
when
and
<=
-
+maximum-insettie-epsilon
displacementtie-epsilon
<=radius-squaredmaximum-radius-squared
%surface-frame-point-in-support-footprint-ppointcenteru-axisv-axistie-epsilon
case
%surface-frame-candidate-relationradius-squareddisplacementpointbest-radius-squaredbest-displacementbest-pointtie-epsilonradius-squared-tie-epsilonpoint-squared-tie-epsilon
:replace
setfbest-radius-squaredradius-squaredbest-displacementdisplacementbest-pointpointhits
list
listkindstockprimitive-normalpoint
:tie
push
listkindstockprimitive-normalpoint
hits
mesh
unlesshits
error"Face chart point (~S,~S) on ~S misses the finished surface."uvface
let*
unit-normals
remove-duplicates
mapcar
lambda
hit
hits
:test
lambda
leftright
>
-1.0d01.0d-10
normal
pointbest-point
%make-surface-attachment-frame
map'
simple-arraysingle-float
3
lambda
coordinate
coerce'single-float
point
map'
simple-arraysingle-float
3
lambda
component
coercecomponent'single-float
normal
map'
simple-arraysingle-float
3
lambda
component
coercecomponent'single-float
tangent
sort
remove-duplicates
mapcar#'firsthits
#'<:key
lambda
kind
ecasekind
:face0
:band1
:junction2
sort
remove-duplicates
mapcar#'secondhits
#'<