input: xyz: (n, 3), new_xyz: (m, 3), feat: (n, c), idx: (m, nsample), offset: (b), new_offset: (b) output: new_feat: (m, c+3, nsample), grouped_idx: (m, nsample)
(nsample, xyz, new_xyz, feat, idx, offset, new_offset, use_xyz=True, return_indx=False)
| 646 | attention_step2_with_rel_pos_value_v2 = AttentionStep2WithRelPosValue_v2.apply |
| 647 | |
| 648 | def queryandgroup(nsample, xyz, new_xyz, feat, idx, offset, new_offset, use_xyz=True, return_indx=False): |
| 649 | """ |
| 650 | input: xyz: (n, 3), new_xyz: (m, 3), feat: (n, c), idx: (m, nsample), offset: (b), new_offset: (b) |
| 651 | output: new_feat: (m, c+3, nsample), grouped_idx: (m, nsample) |
| 652 | """ |
| 653 | assert xyz.is_contiguous() and new_xyz.is_contiguous() and feat.is_contiguous() |
| 654 | if new_xyz is None: |
| 655 | new_xyz = xyz |
| 656 | if idx is None: |
| 657 | idx, _ = knnquery(nsample, xyz, new_xyz, offset, new_offset) # (m, nsample) |
| 658 | |
| 659 | n, m, c = xyz.shape[0], new_xyz.shape[0], feat.shape[1] |
| 660 | grouped_xyz = xyz[idx.view(-1).long(), :].view(m, nsample, 3) # (m, nsample, 3) |
| 661 | #grouped_xyz = grouping(xyz, idx) # (m, nsample, 3) |
| 662 | # 相对位置 |
| 663 | grouped_xyz -= new_xyz.unsqueeze(1) # (m, nsample, 3) |
| 664 | grouped_feat = feat[idx.view(-1).long(), :].view(m, nsample, c) # (m, nsample, c) |
| 665 | #grouped_feat = grouping(feat, idx) # (m, nsample, c) |
| 666 | if use_xyz: |
| 667 | if return_indx: |
| 668 | return torch.cat((grouped_xyz, grouped_feat), -1), idx # (m, nsample, 3+c) |
| 669 | else: |
| 670 | return torch.cat((grouped_xyz, grouped_feat), -1) |
| 671 | else: |
| 672 | if return_indx: |
| 673 | return grouped_feat, idx |
| 674 | else: |
| 675 | return grouped_feat |
| 676 | |
| 677 | |
| 678 | def Divide2Patch(nsample, xyz, offset, return_offset=False, anchor_scale=None): |
nothing calls this directly
no outgoing calls
no test coverage detected