1 /** 2 Copyright: Copyright (c) 2016-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.algorithm.arraycopy3d; 7 8 import voxelman.math; 9 10 /// writes source to a box within dest 11 void setSubArray3d(T)( 12 T[] dest, 13 ivec3 destSize, // 7x8x9 14 ivec3 destPos, 15 T[] source, 16 ivec3 sourceSize, // 4x5x6 17 Box sourceBox, // (1,2,3) 2x3x4 18 ) @nogc 19 { 20 assert(dest.length == destSize.x * destSize.y * destSize.z); 21 assert(source.length == sourceSize.x * sourceSize.y * sourceSize.z); 22 23 const auto dest_size_y = destSize.x * destSize.z; // 1 y slice 24 const auto source_size_y = sourceSize.x * sourceSize.z; // 1 y slice 25 26 foreach(y; 0..sourceBox.size.y) 27 foreach(z; 0..sourceBox.size.z) 28 { 29 auto destY = y + destPos.y; 30 auto destZ = z + destPos.z; 31 auto fromDest = destY * dest_size_y + destZ * destSize.x + destPos.x; 32 auto toDest = fromDest + sourceBox.size.x; 33 34 auto sourceY = y + sourceBox.position.y; 35 auto sourceZ = z + sourceBox.position.z; 36 auto fromSource = sourceY * source_size_y + sourceZ * sourceSize.x + sourceBox.position.x; 37 auto toSource = fromSource + sourceBox.size.x; 38 39 dest[fromDest..toDest] = source[fromSource..toSource]; 40 } 41 } 42 43 /// writes full source to a box within dest 44 void setSubArray3d(T)(T[] dest, ivec3 destSize, Box box, T[] source) @nogc 45 { 46 const int dest_size_y = destSize.x * destSize.z; // 1 y slice 47 assert(dest.length == dest_size_y * destSize.y); 48 assert(source.length == box.volume); 49 50 if (box.position.x == 0 && box.size.x == destSize.x) 51 { 52 if (box.position.z == 0 && box.size.z == destSize.z) 53 { 54 if (box.position.y == 0 && box.size.y == destSize.y) 55 { 56 dest[] = source; 57 } 58 else 59 { 60 auto from = box.position.y * dest_size_y; 61 auto to = (box.position.y + box.size.y) * dest_size_y; 62 dest[from..to] = source; 63 } 64 } 65 else 66 { 67 auto box_size_sqr = box.size.x * box.size.z; 68 foreach(y; box.position.y..(box.position.y + box.size.y)) 69 { 70 auto fromDest = y * dest_size_y + box.position.z * destSize.x; 71 auto toDest = y * dest_size_y + (box.position.z + box.size.z) * destSize.x; 72 auto sourceY = y - box.position.y; 73 auto fromSource = sourceY * box_size_sqr + box.size.z; 74 auto toSource = sourceY * box_size_sqr + box.position.z * box.size.z; 75 dest[fromDest..toDest] = source[fromSource..toSource]; 76 } 77 } 78 } 79 else 80 { 81 int posx = box.position.x; 82 int endx = box.position.x + box.size.x; 83 int endy = box.position.y + box.size.y; 84 int endz = box.position.z + box.size.z; 85 auto box_size_sqr = box.size.x * box.size.z; 86 87 foreach(y; box.position.y..endy) 88 foreach(z; box.position.z..endz) 89 { 90 auto fromDest = y * dest_size_y + z * destSize.x + box.position.x; 91 auto toDest = fromDest + box.size.x; 92 auto sourceY = y - box.position.y; 93 auto sourceZ = z - box.position.z; 94 auto fromSource = sourceY * box_size_sqr + sourceZ * box.size.x; 95 auto toSource = fromSource + box.size.x; 96 97 dest[fromDest..toDest] = source[fromSource..toSource]; 98 } 99 } 100 } 101 102 void setSubArray3d(T)(T[] dest, ivec3 destSize, Box box, T item) @nogc 103 { 104 const int dest_size_y = destSize.x * destSize.z; // 1 y slice 105 assert(dest.length == destSize.x * destSize.y * destSize.z); 106 107 if (box.position.x == 0 && box.size.x == destSize.x) 108 { 109 if (box.position.z == 0 && box.size.z == destSize.z) 110 { 111 if (box.position.y == 0 && box.size.y == destSize.y) 112 { 113 dest[] = item; 114 } 115 else 116 { 117 auto from = box.position.y * dest_size_y; 118 auto to = (box.position.y + box.size.y) * dest_size_y; 119 dest[from..to] = item; 120 } 121 } 122 else 123 { 124 foreach(y; box.position.y..(box.position.y + box.size.y)) 125 { 126 auto from = y * dest_size_y + box.position.z * destSize.x; 127 auto to = y * dest_size_y + (box.position.z + box.size.z) * destSize.x; 128 dest[from..to] = item; 129 } 130 } 131 } 132 else 133 { 134 int endy = box.position.y + box.size.y; 135 int endz = box.position.z + box.size.z; 136 foreach(y; box.position.y..endy) 137 foreach(z; box.position.z..endz) 138 { 139 auto from = y * dest_size_y + z * destSize.x + box.position.x; 140 auto to = from + box.size.x; 141 dest[from..to] = item; 142 } 143 } 144 }