Pin every dense track to the feature whose presence it follows
The absence mapping was asserted for two of the ten dense tracks. Each block hands `pack` an :absent predicate that derives a feature from a track INDEX, so the predicate and the vector literal beside it agree only by hand, in four places — and three of the four blocks had nothing checking them. Give each feature a DIFFERENT gap window, so a track wired to the wrong feature shows up as absence inside somebody else's window. A single shared window passes under any permutation, which is the failure port-plan mechanical fact #2 warns about: swap left for right and every part is still roughly where it belongs, so it survives inspection. Verified by mutation, since a test that cannot fail is worth nothing. Swapping the brow block's two tracks, and swapping eye-block tracks 1 and 3 while leaving 0 and 2 correct, both now fail loudly; neither was caught before. Also pin the teeth. They are their own feature so they can carry their own :area :teeth parameters, which means an occluded mouth sets no bit on them; they are dropped regardless because they stencil on :mouth-in and scene/finish drops a node whose stencil drew nothing. Both frames come from an unannotated reference clip, because the interior only draws on an open mouth and a frame the mouth was shut on would have passed for the wrong reason. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B87NVmiU36qQmN9gmFYnJ9
This commit is contained in:
parent
35ef150b48
commit
b6517f837a
1 changed files with 95 additions and 0 deletions
|
|
@ -402,6 +402,101 @@
|
|||
(is (contains? drawn-nodes :mouth)))
|
||||
(is (empty? (scene/problems sc)))))
|
||||
|
||||
(deftest each-dense-track-follows-its-own-features-presence
|
||||
;; Every feature is given a DIFFERENT gap, so a track wired to the wrong one
|
||||
;; shows up as absence inside somebody else's window. One shared gap would pass
|
||||
;; under any permutation of the four tracks in the eye block, and that is the
|
||||
;; failure docs/port-plan.md warns about twice: swap left for right and every
|
||||
;; part is still roughly where it belongs, so it survives inspection.
|
||||
;;
|
||||
;; This is the mapping `pack` cannot check for itself. Each block hands it an
|
||||
;; :absent predicate that derives a feature from a track INDEX, so the predicate
|
||||
;; and the vector literal beside it have to agree by hand, in four places.
|
||||
(let [windows {:eye-r (set (range 10 15))
|
||||
:eye-l (set (range 20 25))
|
||||
:brow-r (set (range 30 35))
|
||||
:brow-l (set (range 40 45))}
|
||||
presence (into {} (map (fn [[id gap]]
|
||||
[id (mapv #(not (contains? gap %))
|
||||
(range take/frames))]))
|
||||
windows)
|
||||
c (freeze/clip (assoc take/params :name "per-track-gaps")
|
||||
(assoc @take/measured :presence presence))
|
||||
sc (:scene c)
|
||||
at (fn [id path f]
|
||||
(ch/value-at (get-in sc [:nodes id :channels path]) f (:store c)))
|
||||
;; Node, channel, and the feature whose gap it must follow. Every dense
|
||||
;; track of the eye, iris, brow and brow-position blocks appears once.
|
||||
tracks [[:eye-r [:geom :pts] :eye-r]
|
||||
[:eye-r-in [:geom :pts] :eye-r]
|
||||
[:eye-l [:geom :pts] :eye-l]
|
||||
[:eye-l-in [:geom :pts] :eye-l]
|
||||
[:iris-r [:xform :pos] :eye-r]
|
||||
[:iris-l [:xform :pos] :eye-l]
|
||||
[:brow-r [:geom :pts] :brow-r]
|
||||
[:brow-l [:geom :pts] :brow-l]
|
||||
[:brow-r [:xform :pos] :brow-r]
|
||||
[:brow-l [:xform :pos] :brow-l]]]
|
||||
(is (empty? (scene/problems sc)))
|
||||
(doseq [[id path owner] tracks
|
||||
[feature gap] windows
|
||||
f gap]
|
||||
(if (= feature owner)
|
||||
(is (ch/nothing? (at id path f))
|
||||
(str id " " path " is not absent at " f " with " feature " occluded"))
|
||||
(is (not (ch/nothing? (at id path f)))
|
||||
(str id " " path " follows " feature "'s gap at frame " f))))))
|
||||
|
||||
(deftest teeth-follow-the-mouth-through-their-stencil-and-not-through-a-mask
|
||||
;; Teeth are their own feature, so that they can carry their own :area :teeth
|
||||
;; parameters — which means an occluded MOUTH sets no absence bit on them. They
|
||||
;; do not need one: they are stencilled by :mouth-in, and scene/finish drops a
|
||||
;; node whose stencil drew nothing. So the coupling is real, and it is the
|
||||
;; stencil rule rather than the mask that enforces it. The rule itself is
|
||||
;; asserted in scene-test; what is pinned here is the wiring that relies on it.
|
||||
(let [gap (set (range 40 60))
|
||||
teeth-in {;; The mouth's own inner ring standing in for a pixel-derived
|
||||
;; contour: real geometry and no nils, so every frame has a
|
||||
;; value that could be dropped.
|
||||
:contours (:inner @take/measured)
|
||||
:shown (vec (repeat take/frames true))}
|
||||
clip (fn [nm extra]
|
||||
(freeze/clip (assoc take/params :name nm)
|
||||
(merge (assoc @take/measured :teeth teeth-in) extra)))
|
||||
ref (clip "teeth-reference" nil)
|
||||
occ (clip "teeth-mouth-gap"
|
||||
{:presence {:mouth (mapv #(not (contains? gap %))
|
||||
(range take/frames))}})
|
||||
;; Hoisted: the resolver caches its order and reuses its buffers, so the
|
||||
;; node ids come out before the next frame is asked for.
|
||||
nodes-at (fn [c]
|
||||
(let [r (scene/resolver (:scene c) (:store c) pal/index-of)]
|
||||
(fn [f] (into #{} (map :node) (r f)))))
|
||||
ref-at (nodes-at ref)
|
||||
occ-at (nodes-at occ)
|
||||
;; The interior only draws on an OPEN mouth, so both frames are picked
|
||||
;; from the UNANNOTATED clip. Same articulation either side of the gap,
|
||||
;; which is what stops this passing on a frame the mouth was shut anyway.
|
||||
open (filter #(contains? (ref-at %) :teeth) (range take/frames))
|
||||
inside (first (filter gap open))
|
||||
outside (first (remove gap open))]
|
||||
(is (= :mouth-in (get-in (:scene occ) [:nodes :teeth :stencil]))
|
||||
"teeth stop inheriting the mouth's absence if this stops being their stencil")
|
||||
(is (some? inside) "no open-mouth frame inside the gap to test with")
|
||||
(is (some? outside) "no open-mouth frame outside the gap to test with")
|
||||
(when (and inside outside)
|
||||
;; Annotating the MOUTH sets no bit on the teeth: they are a feature of
|
||||
;; their own and nothing named them.
|
||||
(is (not (ch/nothing?
|
||||
(ch/value-at (get-in (:scene occ) [:nodes :teeth :channels [:geom :pts]])
|
||||
inside (:store occ)))))
|
||||
;; They are dropped anyway — :mouth-in drew nothing to clip them against.
|
||||
(is (not (contains? (occ-at inside) :mouth-in)))
|
||||
(is (not (contains? (occ-at inside) :teeth)))
|
||||
;; And the same articulation outside the gap still draws them.
|
||||
(is (contains? (occ-at outside) :teeth)))
|
||||
(is (empty? (scene/problems (:scene occ))))))
|
||||
|
||||
(deftest an-undetected-frame-has-no-pose-at-all
|
||||
;; A subject that was not on the frame has NO VALUE, which is different from a
|
||||
;; part being switched off. The mask lands on every block of the freeze, so an
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue