NuTo
Numerics Tool
MortonOrder.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <limits>
4 namespace NuTo
5 {
10 
12 {
13 public:
14  static uint32_t EncodeMorton3D(uint32_t x, uint32_t y, uint32_t z)
15  {
16  return ((Part1By2(z) << 2) + (Part1By2(y) << 1) + Part1By2(x));
17  }
18 
19  // "Insert" a 0 bit after each of the 16 low bits of x
20  static uint32_t Part1By1(uint32_t x)
21  {
22  x &= 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210
23  x = (x ^ (x << 8)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
24  x = (x ^ (x << 4)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
25  x = (x ^ (x << 2)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
26  x = (x ^ (x << 1)) & 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
27  return x;
28  }
29 
30  // "Insert" two 0 bits after each of the 10 low bits of x
31  static uint32_t Part1By2(uint32_t x)
32  {
33  x &= 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210
34  x = (x ^ (x << 16)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210
35  x = (x ^ (x << 8)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210
36  x = (x ^ (x << 4)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10
37  x = (x ^ (x << 2)) & 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
38  return x;
39  }
40  // Inverse of Part1By1 - "delete" all odd-indexed bits
41  static uint32_t Compact1By1(uint32_t x)
42  {
43  x &= 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
44  x = (x ^ (x >> 1)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
45  x = (x ^ (x >> 2)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
46  x = (x ^ (x >> 4)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
47  x = (x ^ (x >> 8)) & 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210
48  return x;
49  }
50 
51  // Inverse of Part1By2 - "delete" all bits not at positions divisible by 3
52  static uint32_t Compact1By2(uint32_t x)
53  {
54  x &= 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
55  x = (x ^ (x >> 2)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10
56  x = (x ^ (x >> 4)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210
57  x = (x ^ (x >> 8)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210
58  x = (x ^ (x >> 16)) & 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210
59  return x;
60  }
61 
62  static uint32_t DecodeMorton2X(uint32_t code)
63  {
64  return Compact1By1(code >> 0);
65  }
66 
67  static uint32_t DecodeMorton2Y(uint32_t code)
68  {
69  return Compact1By1(code >> 1);
70  }
71 
72  static uint32_t DecodeMorton3X(uint32_t code)
73  {
74  return Compact1By2(code >> 0);
75  }
76 
77  static uint32_t DecodeMorton3Y(uint32_t code)
78  {
79  return Compact1By2(code >> 1);
80  }
81 
82  static uint32_t DecodeMorton3Z(uint32_t code)
83  {
84  return Compact1By2(code >> 2);
85  }
87  static uint32_t Neighbor3D(uint32_t key, uint32_t dx, uint32_t dy, uint32_t dz)
88  {
89  uint32_t x = DecodeMorton3X(key);
90  uint32_t y = DecodeMorton3Y(key);
91  uint32_t z = DecodeMorton3Z(key);
92  return EncodeMorton3D(x + dx, y + dy, z + dz);
93  // return ((Part1By2(z+dz)<<2)+(Part1By2(y+dy)<<1)+Part1By2(x+dx));
94  }
96  static uint32_t NegNeighbor3D(uint32_t key, int32_t dx, int32_t dy, int32_t dz)
97  {
98  int32_t x = (int32_t)DecodeMorton3X(key);
99  int32_t y = (int32_t)DecodeMorton3Y(key);
100  int32_t z = (int32_t)DecodeMorton3Z(key);
101  if (x + dx < 0 || y + dy < 0 || z + dz < 0)
102  return std::numeric_limits<uint32_t>::max(); // return max value, to have one neighbor which does not exist
103  else
104  return EncodeMorton3D(x + dx, y + dy, z + dz);
105  // return ((Part1By2(z+dz)<<2)+(Part1By2(y+dy)<<1)+Part1By2(x+dx));
106  }
107 };
108 } // namespace NuTo
static uint32_t Compact1By1(uint32_t x)
Definition: MortonOrder.h:41
class for sorting in Morton order (z-order as space filling curve)
Definition: MortonOrder.h:11
static uint32_t DecodeMorton3Y(uint32_t code)
Definition: MortonOrder.h:77
static uint32_t Neighbor3D(uint32_t key, uint32_t dx, uint32_t dy, uint32_t dz)
calculates neighbor of key shifted by +x+y+z
Definition: MortonOrder.h:87
static uint32_t Compact1By2(uint32_t x)
Definition: MortonOrder.h:52
static uint32_t DecodeMorton3Z(uint32_t code)
Definition: MortonOrder.h:82
static uint32_t DecodeMorton2Y(uint32_t code)
Definition: MortonOrder.h:67
static uint32_t DecodeMorton3X(uint32_t code)
Definition: MortonOrder.h:72
static uint32_t Part1By1(uint32_t x)
Definition: MortonOrder.h:20
static uint32_t NegNeighbor3D(uint32_t key, int32_t dx, int32_t dy, int32_t dz)
calculates neighbor of key shifted by +x+y+z
Definition: MortonOrder.h:96
Definition: Exception.h:6
static uint32_t EncodeMorton3D(uint32_t x, uint32_t y, uint32_t z)
Definition: MortonOrder.h:14
static uint32_t Part1By2(uint32_t x)
Definition: MortonOrder.h:31
static uint32_t DecodeMorton2X(uint32_t code)
Definition: MortonOrder.h:62