The jbeam maintainer marked up two node orderings on renders of his gen4 body. One of them is a config miss, the other one the transform cannot produce at any setting.
The first five left-side vertices of examples/regression_jbeam/y-sorting-repro.jbeam are real positions from gen4_body, the same file as in #214, and show the problem:
| X |
Y |
Z |
column |
| 0.953 |
-1.967 |
0.122 |
inner |
| 0.920 |
-1.953 |
0.439 |
inner |
| 0.780 |
-1.815 |
0.719 |
inner |
| 1.036 |
-1.807 |
0.125 |
outer |
| 0.998 |
-1.791 |
0.473 |
outer |
They form two vertical columns, the nose face and the fender beside it. With y-sorting-threshold: 0.31 all five land in one band, and the band is sorted by Z, so the output climbs the inner column, jumps to the outer one, comes back, jumps again:
0.953 1.036 0.920 0.998 0.780
What the maintainer wants is one column at a time, each from the bottom up.
No threshold fixes this. Y and Z both interleave between the columns, so only X separates them. Searching every one of the 1848 distinct Y thresholds that file admits, the front needs 0.153 to 0.16 and the rear corner of the same file needs above 0.299. Those windows do not overlap, so one setting cannot serve both.
The fix is a second banding pass on the absolute X value inside each Y band, using the same rule Y already uses (a new band starts when a vertex sits at least the threshold from the vertex that opened it), applied before the Z sort. Sorting then becomes Y band, X band, Z, X.
That touches three places in Transformation.hs. indexBand reads ySortingThreshold straight out of the config and would take a coordinate accessor and a threshold instead, so it can serve both passes. sortVertices runs one mapAccumL indexBand over the whole group and would group by Y band first and index X within each. compareAV gets one more term between compareY and compareZ.
It needs a config key, and that key should be absent by default so no existing output changes. A relative threshold that scales with vehicle width was considered and rejected: a fraction of the group's half width depends on which vertices happen to be in the group, so one vertex far out moves the boundary for all the others. The config is read per vehicle anyway, the same way y-sorting-threshold already is. 0.20 is the value that satisfies both of the maintainer's requests on his file.
There is a failing test for this on x-column-sorting. Note that the threshold in it is not free choice: between 0.153 and 0.16 the Y bands happen to land on exactly the two columns and the assertion passes with nothing fixed at all.
The jbeam maintainer marked up two node orderings on renders of his gen4 body. One of them is a config miss, the other one the transform cannot produce at any setting.
The first five left-side vertices of
examples/regression_jbeam/y-sorting-repro.jbeamare real positions fromgen4_body, the same file as in #214, and show the problem:They form two vertical columns, the nose face and the fender beside it. With
y-sorting-threshold: 0.31all five land in one band, and the band is sorted by Z, so the output climbs the inner column, jumps to the outer one, comes back, jumps again:What the maintainer wants is one column at a time, each from the bottom up.
No threshold fixes this. Y and Z both interleave between the columns, so only X separates them. Searching every one of the 1848 distinct Y thresholds that file admits, the front needs 0.153 to 0.16 and the rear corner of the same file needs above 0.299. Those windows do not overlap, so one setting cannot serve both.
The fix is a second banding pass on the absolute X value inside each Y band, using the same rule Y already uses (a new band starts when a vertex sits at least the threshold from the vertex that opened it), applied before the Z sort. Sorting then becomes Y band, X band, Z, X.
That touches three places in
Transformation.hs.indexBandreadsySortingThresholdstraight out of the config and would take a coordinate accessor and a threshold instead, so it can serve both passes.sortVerticesruns onemapAccumL indexBandover the whole group and would group by Y band first and index X within each.compareAVgets one more term betweencompareYandcompareZ.It needs a config key, and that key should be absent by default so no existing output changes. A relative threshold that scales with vehicle width was considered and rejected: a fraction of the group's half width depends on which vertices happen to be in the group, so one vertex far out moves the boundary for all the others. The config is read per vehicle anyway, the same way
y-sorting-thresholdalready is. 0.20 is the value that satisfies both of the maintainer's requests on his file.There is a failing test for this on
x-column-sorting. Note that the threshold in it is not free choice: between 0.153 and 0.16 the Y bands happen to land on exactly the two columns and the assertion passes with nothing fixed at all.