Skip to content

Sorting a Y band by Z alone interleaves vertices that belong to different X columns #234

Description

@webdevred

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions