Fix sign propagation bug.
Fix sign propagation bug.

MeshToVolume uses axis-aligned rayfires to detect voxels that
are clearly "outside" the volume.  (Connected to infinity by voxels
with dist > 0.75). This does not detect all such voxels, as there may be
voxels that are "in shadow". It therefore then propagates the "outside"
state to adjacent voxels with dist >0.75.

For reasons of performance, the existing algorithm separates
propagation within a node (contiguous memory) and between nodes.
It also uses a mask to avoid performing unnecessary work where
nothing has changed. I believe the logic around the mask is
overaggressive, and leads to some edge cases where necessary
propagation doesn't occur across node boundaries. This leads to
voxels incorrectly being marked "inside", which can result in very
visible shape changes in the result.

 - The previous logic was (I believe) as follows:
    On each pass
      - propagate within each node for all changed nodes.
      - reduce the set of changed nodes to only those that
         were changed by this propagation.
      - For each node A that was **not** changed
           - For each adjacent node B that was changed
               - Propagate outsideness from B to A across the node
                  boundary. (This is actually stored as a pending update
                  that is applied later).
               - Mark node A as a node that should be considered changed
                  in the next pass.
      - Apply the pending updates, swap the "changed this pass" mask
        over the "changed last pass" record, and repeat.

I am confused by this, although I may not have fully understood -
simply because a node was changed by the within-node propagation,
I don't see why that means we should not then attempt to propagate from
adjacent nodes, especially since in the next pass the adjacent node may
not be marked as "changed" and so may not propagate at all.

We have seen a real example where a few voxels on the edge
of a node get the wrong signed distance.
The adjacent node gets its outsidedness set correctly for dist > 0.75 by
the sweeping op. Therefore when we propagate within that node
it is marked "unchanged", and we do not propagate from that node
to adjacent nodes.

 - The new logic is:
    On each pass
      - propagate within each node for all changed nodes.
      - For each node A
           - For each adjacent node B that was changed
               - Propagate outsideness from B to A across the node
                  boundary. (This is actually stored as a pending update
                  that is applied later).
               - Mark node A as a node that should be considered changed
                  in the next pass.
      - Apply the pending updates, swap the "changed this pass" mask
        over the "changed last pass" record, and repeat.

I do not think the performance impact of this will be too great - the
greatest benefit of the masking would seem to be a case where an
internal tunnel means the loop is repeated many times, with only
a few nodes changing each time. In this case, for each pass and
for every node, we do 6 node offsets and lookups into the mask array.
These lookups will still almost all return "false", so we do not do
the (comparatively expensive) cross-node propagation.

Signed-off-by: Tristan Barback <39775a9435a23f4dc3000512ffbe965ce2998bac@autodesk.com>

dreamworksanimation/openvdb,dreamworksanimation/openvdb,dreamworksanimation/openvdb,dreamworksanimation/openvdb