| 63 | # x: SparseTensor, z: PointTensor |
| 64 | # return: PointTensor |
| 65 | def voxel_to_point(x, z, nearest=False): |
| 66 | if z.idx_query is None or z.weights is None or z.idx_query.get( |
| 67 | x.s) is None or z.weights.get(x.s) is None: |
| 68 | kr = KernelRegion(2, x.s, 1) |
| 69 | off = kr.get_kernel_offset().to(z.F.device) |
| 70 | #old_hash = kernel_hash_gpu(torch.floor(z.C).int(), off) |
| 71 | old_hash = spf.sphash( |
| 72 | torch.cat([ |
| 73 | torch.floor(z.C[:, :3] / x.s).int() * x.s, |
| 74 | z.C[:, -1].int().view(-1, 1) |
| 75 | ], 1), off) |
| 76 | pc_hash = spf.sphash(x.C.to(z.F.device)) |
| 77 | idx_query = spf.sphashquery(old_hash, pc_hash) |
| 78 | weights = spf.calc_ti_weights(z.C, idx_query, |
| 79 | scale=x.s).transpose(0, 1).contiguous() |
| 80 | idx_query = idx_query.transpose(0, 1).contiguous() |
| 81 | if nearest: |
| 82 | weights[:, 1:] = 0. |
| 83 | idx_query[:, 1:] = -1 |
| 84 | new_feat = spf.spdevoxelize(x.F, idx_query, weights) |
| 85 | new_tensor = PointTensor(new_feat, |
| 86 | z.C, |
| 87 | idx_query=z.idx_query, |
| 88 | weights=z.weights) |
| 89 | new_tensor.additional_features = z.additional_features |
| 90 | new_tensor.idx_query[x.s] = idx_query |
| 91 | new_tensor.weights[x.s] = weights |
| 92 | z.idx_query[x.s] = idx_query |
| 93 | z.weights[x.s] = weights |
| 94 | |
| 95 | else: |
| 96 | new_feat = spf.spdevoxelize(x.F, z.idx_query.get(x.s), z.weights.get(x.s)) |
| 97 | new_tensor = PointTensor(new_feat, |
| 98 | z.C, |
| 99 | idx_query=z.idx_query, |
| 100 | weights=z.weights) |
| 101 | new_tensor.additional_features = z.additional_features |
| 102 | |
| 103 | return new_tensor |
| 104 | |
| 105 | |