File size: 2,065 Bytes
4893ce0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import torch
from .z_order import xyz2key as z_order_encode_
from .z_order import key2xyz as z_order_decode_
from .hilbert import encode as hilbert_encode_
from .hilbert import decode as hilbert_decode_
@torch.inference_mode()
def encode(grid_coord, batch=None, depth=16, order="z"):
assert order in {"z", "z-trans", "hilbert", "hilbert-trans"}
if order == "z":
code = z_order_encode(grid_coord, depth=depth)
elif order == "z-trans":
code = z_order_encode(grid_coord[:, [1, 0, 2]], depth=depth)
elif order == "hilbert":
code = hilbert_encode(grid_coord, depth=depth)
elif order == "hilbert-trans":
code = hilbert_encode(grid_coord[:, [1, 0, 2]], depth=depth)
else:
raise NotImplementedError
if batch is not None:
batch = batch.long()
code = batch << depth * 3 | code
return code
@torch.inference_mode()
def decode(code, depth=16, order="z"):
assert order in {"z", "hilbert"}
batch = code >> depth * 3
code = code & ((1 << depth * 3) - 1)
if order == "z":
grid_coord = z_order_decode(code, depth=depth)
elif order == "hilbert":
grid_coord = hilbert_decode(code, depth=depth)
else:
raise NotImplementedError
return grid_coord, batch
def z_order_encode(grid_coord: torch.Tensor, depth: int = 16):
x, y, z = grid_coord[:, 0].long(), grid_coord[:, 1].long(), grid_coord[:, 2].long()
# we block the support to batch, maintain batched code in Point class
code = z_order_encode_(x, y, z, b=None, depth=depth)
return code
def z_order_decode(code: torch.Tensor, depth):
x, y, z = z_order_decode_(code, depth=depth)
grid_coord = torch.stack([x, y, z], dim=-1) # (N, 3)
return grid_coord
def hilbert_encode(grid_coord: torch.Tensor, depth: int = 16):
return hilbert_encode_(grid_coord, num_dims=3, num_bits=depth)
def hilbert_decode(code: torch.Tensor, depth: int = 16):
return hilbert_decode_(code, num_dims=3, num_bits=depth)
|