packer_3d/
lib.rs

1/*! Rust Crate for 3-dimensional packing of boxes optimally along x, y or z, or all three axis.
2## Example
3```
4let my_boxes = vec![
5    Box3D::from_xyz_whl(0, 0, 0, 100, 200, 300, 1, 0),
6    Box3D::from_xyz_whl(0, 0, 0, 100, 200, 300, 2, 0),
7    Box3D::from_xyz_whl(0, 0, 0, 100, 200, 300, 3, 0),
8];
9
10let mut my_instance = PackerInstance::new(
11    my_boxes.clone(),            // Our boxes
12    Vector3D::new(500, 0, 500),  // Our container size
13    true,                        // No rotations
14    (false, true, false),        // Minimize height only
15    Sorting::descending_volume,  // Our initial sorting heuristic
16);
17
18// for _ in 0..3 {
19//     match my_instance.pack_next() {
20//         Err(error) => println!("Error: {}", error),
21//         Ok(()) => {}
22//     }
23// }
24
25match my_instance.pack_all() {
26    Err(errors) => println!("Errors: {:#?}", errors),
27    Ok(()) => {}
28}
29
30println!("{:#?}", my_instance.boxes());
31```*/
32
33pub mod box3d;
34pub mod vector3d;
35pub mod sorting;
36
37use box3d::Box3D;
38use vector3d::Vector3D;
39use std::cmp::Ordering;
40
41use std::collections::HashSet;
42use std::hash::BuildHasherDefault;
43use fnv::FnvHasher;
44
45/// Hash Set using [fnv](https://crates.io/crates/fnv): an implementation of the [Fowler–Noll–Vo hash function](http://www.isthe.com/chongo/tech/comp/fnv/index.html).
46/// ## Example
47/// ```rust
48/// let mut boxes = HashSetFnv::<Box3D>::default();
49/// boxes.insert(Box3D::from_xyz_whl(0, 0, 0, 100, 200, 300, 1, 0));
50/// ```
51pub type HashSetFnv<V> = HashSet<V, BuildHasherDefault<FnvHasher>>;
52
53/// # Minimize tuple
54/// Dictates which axis (x,y,z) the packer tries to minimize
55/// ## Example
56/// ```rust
57/// // x,    y,     z
58/// (true, false, true)
59/// ```
60/// Will minimize the width (x) of the container,\
61/// and the length (z) of the container\
62/// However, the height (y) of the container will be specified via container_size in [PackerInstance::new()](PackerInstance::new)
63pub type Minimize = (bool, bool, bool);
64
65/**
66## Example
67```
68let mut my_instance = PackerInstance::new(
69    my_boxes.clone(), // Our boxes
70    Vector3D::new(500, 0, 500), // Our container size
71    true, // Allow rotations
72    (false, true, false), // Minimize height only
73    Sorting::descending_volume // Our initial sorting heuristic
74);
75```*/
76#[derive(Default, Debug, Clone)]
77pub struct PackerInstance {
78	container_size: Vector3D::<u64>,
79	do_rotations: bool,
80	minimize: Minimize,
81
82	boxes: Vec<Box3D>,
83	holes: HashSetFnv<Box3D>,
84
85	next_box_id: usize,
86	next_hole_id: usize,
87}
88
89impl PackerInstance {
90	pub fn container_size(&self) -> Vector3D<u64> {
91		self.container_size
92	}
93
94	pub fn boxes(&self) -> &Vec<Box3D> {
95		&self.boxes
96	}
97
98	pub fn holes(&self) -> &HashSetFnv<Box3D> {
99		&self.holes
100	}
101
102	pub fn finished(&self) -> bool {
103		self.next_box_id >= self.boxes.len()
104	}
105
106	pub fn next_box_id(&self) -> usize {
107		self.next_box_id
108	}
109
110	pub fn next_hole_id(&self) -> usize {
111		self.next_hole_id
112	}
113
114	/// Setup the packer
115	pub fn new(mut boxes: Vec<Box3D>, container_size: Vector3D<u64>, do_rotations: bool, minimize: Minimize, sorting_func: fn(&Box3D,&Box3D) -> Ordering)
116	-> PackerInstance
117	{
118		boxes.sort_by(sorting_func);
119
120		let mut holes = HashSetFnv::<Box3D>::default();
121		holes.insert(Box3D::from_xyz_whl(
122			0, 0, 0,
123			if minimize.0 {u64::MAX} else {container_size.x},
124			if minimize.1 {u64::MAX} else {container_size.y},
125			if minimize.2 {u64::MAX} else {container_size.z},
126			0,
127			0
128		));
129
130		PackerInstance {
131			container_size,
132			do_rotations,
133			minimize,
134			boxes,
135			holes,
136			next_box_id: 0,
137			next_hole_id: 1
138		}
139	}
140
141	/// Do next packing iteration
142	pub fn pack_next(&mut self) -> Result<(), String>
143	{
144		if self.next_box_id >= self.boxes.len() {
145			return Err("No more boxes to pack".into());
146		}
147
148		let b = &mut self.boxes[self.next_box_id];
149		if b.size.x == 0 || b.size.y == 0 || b.size.z == 0
150		{
151			self.next_box_id += 1;
152			return Err(format!("Box {} has invalid size", b.id));
153		}
154
155		let (best_box, best_hole) = get_best_hole(b, &self.holes, self.do_rotations, self.minimize);
156		if best_hole.is_none()
157		{
158			self.next_box_id += 1;
159			return Err(format!("Could not find hole for Box {}", b.id));
160		}
161		let best_hole = best_hole.unwrap();
162
163		// Place and rotate (switch sizes) box
164		b.size = best_box.size;
165		b.position = best_hole.position;
166
167		// Update container size
168		if self.minimize.0 {
169			self.container_size.x = self.container_size.x.max(get_new_w(&best_hole, b));
170		};
171		if self.minimize.1 {
172			self.container_size.y = self.container_size.y.max(get_new_h(&best_hole, b));
173		};
174		if self.minimize.2 {
175			self.container_size.z = self.container_size.z.max(get_new_l(&best_hole, b));
176		};
177
178		// Update the holes
179		self.next_hole_id = update_holes(b, &mut self.holes, self.next_hole_id);
180
181		// Change for next box id
182		self.next_box_id += 1;
183
184		Ok(())
185	}
186
187	pub fn pack_all(&mut self) -> Result<(), Vec<String>> {
188		let mut errors = Vec::new();
189
190		while !self.finished() {
191			if let Err(e) = self.pack_next() {
192				errors.push(e);
193			}
194		}
195
196		if errors.is_empty() {
197			Ok(())
198		} else {
199			Err(errors)
200		}
201    }
202}
203
204fn cut(b: &Box3D, hole: &Box3D, holes: &mut HashSetFnv<Box3D>, next_hole_id: &mut usize)
205{
206	let mut new_holes = Vec::<Box3D>::default();
207
208	let x2 = b.x2();
209	let y2 = b.y2();
210	let z2 = b.z2();
211
212	let hx2 = hole.x2();
213	let hy2 = hole.y2();
214	let hz2 = hole.z2();
215
216	if
217		(b.position.x <= hole.position.x && x2 >= hx2) &&
218		(b.position.y <= hole.position.y && y2 >= hy2) &&
219		(b.position.z <= hole.position.z && z2 >= hz2)
220	{ }
221	else if
222		(b.position.x <= hole.position.x && x2 >= hx2) &&
223		(b.position.y <= hole.position.y && y2 >= hy2) &&
224		(b.position.z <= hole.position.z && z2 < hz2)
225	{
226		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 1));
227	}
228	else if
229		(b.position.x <= hole.position.x && x2 >= hx2) &&
230		(b.position.y <= hole.position.y && y2 >= hy2) &&
231		(b.position.z > hole.position.z && z2 >= hz2)
232	{
233		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 2));
234	}
235	else if
236		(b.position.x <= hole.position.x && x2 >= hx2) &&
237		(b.position.y <= hole.position.y && y2 >= hy2) &&
238		(b.position.z > hole.position.z && z2 < hz2)
239	{
240		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 3));
241		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 4));
242	}
243	else if
244		(b.position.x <= hole.position.x && x2 >= hx2) &&
245		(b.position.y <= hole.position.y && y2 < hy2) &&
246		(b.position.z <= hole.position.z && z2 >= hz2)
247	{
248		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 5));
249	}
250	else if
251		(b.position.x <= hole.position.x && x2 >= hx2) &&
252		(b.position.y <= hole.position.y && y2 < hy2) &&
253		(b.position.z <= hole.position.z && z2 < hz2)
254	{
255		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 6));
256		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 7));
257	}
258	else if
259		(b.position.x <= hole.position.x && x2 >= hx2) &&
260		(b.position.y <= hole.position.y && y2 < hy2) &&
261		(b.position.z > hole.position.z && z2 >= hz2)
262	{
263		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 8));
264		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 9));
265	}
266	else if
267		(b.position.x <= hole.position.x && x2 >= hx2) &&
268		(b.position.y <= hole.position.y && y2 < hy2) &&
269		(b.position.z > hole.position.z && z2 < hz2)
270	{
271		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 10));
272		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 11));
273		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 12));
274	}
275	else if
276		(b.position.x <= hole.position.x && x2 >= hx2) &&
277		(b.position.y > hole.position.y && y2 >= hy2) &&
278		(b.position.z <= hole.position.z && z2 >= hz2)
279	{
280		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 13));
281	}
282	else if
283		(b.position.x <= hole.position.x && x2 >= hx2) &&
284		(b.position.y > hole.position.y && y2 >= hy2) &&
285		(b.position.z <= hole.position.z && z2 < hz2)
286	{
287		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 14));
288		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 15));
289	}
290	else if
291		(b.position.x <= hole.position.x && x2 >= hx2) &&
292		(b.position.y > hole.position.y && y2 >= hy2) &&
293		(b.position.z > hole.position.z && z2 >= hz2)
294	{
295		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 16));
296		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 17));
297	}
298	else if
299		(b.position.x <= hole.position.x && x2 >= hx2) &&
300		(b.position.y > hole.position.y && y2 >= hy2) &&
301		(b.position.z > hole.position.z && z2 < hz2)
302	{
303		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 18));
304		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 19));
305		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 20));
306	}
307	else if
308		(b.position.x <= hole.position.x && x2 >= hx2) &&
309		(b.position.y > hole.position.y && y2 < hy2) &&
310		(b.position.z <= hole.position.z && z2 >= hz2)
311	{
312		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 21));
313		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 22));
314	}
315	else if
316		(b.position.x <= hole.position.x && x2 >= hx2) &&
317		(b.position.y > hole.position.y && y2 < hy2) &&
318		(b.position.z <= hole.position.z && z2 < hz2)
319	{
320		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 23));
321		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 24));
322		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 25));
323	}
324	else if
325		(b.position.x <= hole.position.x && x2 >= hx2) &&
326		(b.position.y > hole.position.y && y2 < hy2) &&
327		(b.position.z > hole.position.z && z2 >= hz2)
328	{
329		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 26));
330		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 27));
331		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 28));
332	}
333	else if
334		(b.position.x <= hole.position.x && x2 >= hx2) &&
335		(b.position.y > hole.position.y && y2 < hy2) &&
336		(b.position.z > hole.position.z && z2 < hz2)
337	{
338		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 29));
339		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 30));
340		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 31));
341		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 32));
342	}
343	else if
344		(b.position.x <= hole.position.x && x2 < hx2) &&
345		(b.position.y <= hole.position.y && y2 >= hy2) &&
346		(b.position.z <= hole.position.z && z2 >= hz2)
347	{
348		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 33));
349	}
350	else if
351		(b.position.x <= hole.position.x && x2 < hx2) &&
352		(b.position.y <= hole.position.y && y2 >= hy2) &&
353		(b.position.z <= hole.position.z && z2 < hz2)
354	{
355		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 34));
356		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 35));
357	}
358	else if
359		(b.position.x <= hole.position.x && x2 < hx2) &&
360		(b.position.y <= hole.position.y && y2 >= hy2) &&
361		(b.position.z > hole.position.z && z2 >= hz2)
362	{
363		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 36));
364		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 37));
365	}
366	else if
367		(b.position.x <= hole.position.x && x2 < hx2) &&
368		(b.position.y <= hole.position.y && y2 >= hy2) &&
369		(b.position.z > hole.position.z && z2 < hz2)
370	{
371		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 38));
372		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 39));
373		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 40));
374	}
375	else if
376		(b.position.x <= hole.position.x && x2 < hx2) &&
377		(b.position.y <= hole.position.y && y2 < hy2) &&
378		(b.position.z <= hole.position.z && z2 >= hz2)
379	{
380		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 41));
381		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 42));
382	}
383	else if
384		(b.position.x <= hole.position.x && x2 < hx2) &&
385		(b.position.y <= hole.position.y && y2 < hy2) &&
386		(b.position.z <= hole.position.z && z2 < hz2)
387	{
388		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 43));
389		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 44));
390		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 45));
391		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 46));
392		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 47));
393		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 48));
394	}
395	else if
396		(b.position.x <= hole.position.x && x2 < hx2) &&
397		(b.position.y <= hole.position.y && y2 < hy2) &&
398		(b.position.z > hole.position.z && z2 >= hz2)
399	{
400		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 49));
401		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 50));
402		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 51));
403		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 52));
404	}
405	else if
406		(b.position.x <= hole.position.x && x2 < hx2) &&
407		(b.position.y <= hole.position.y && y2 < hy2) &&
408		(b.position.z > hole.position.z && z2 < hz2)
409	{
410		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 53));
411		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 54));
412		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 55));
413		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 56));
414		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 57));
415		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 58));
416		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 59));
417		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 60));
418	}
419	else if
420		(b.position.x <= hole.position.x && x2 < hx2) &&
421		(b.position.y > hole.position.y && y2 >= hy2) &&
422		(b.position.z <= hole.position.z && z2 >= hz2)
423	{
424		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 61));
425		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 62));
426	}
427	else if
428		(b.position.x <= hole.position.x && x2 < hx2) &&
429		(b.position.y > hole.position.y && y2 >= hy2) &&
430		(b.position.z <= hole.position.z && z2 < hz2)
431	{
432		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 63));
433		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 64));
434		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 65));
435		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 66));
436	}
437	else if
438		(b.position.x <= hole.position.x && x2 < hx2) &&
439		(b.position.y > hole.position.y && y2 >= hy2) &&
440		(b.position.z > hole.position.z && z2 >= hz2)
441	{
442		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 67));
443		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 68));
444		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 69));
445		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 70));
446	}
447	else if
448		(b.position.x <= hole.position.x && x2 < hx2) &&
449		(b.position.y > hole.position.y && y2 >= hy2) &&
450		(b.position.z > hole.position.z && z2 < hz2)
451	{
452		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 71));
453		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 72));
454		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 73));
455		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 74));
456		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 75));
457	}
458	else if
459		(b.position.x <= hole.position.x && x2 < hx2) &&
460		(b.position.y > hole.position.y && y2 < hy2) &&
461		(b.position.z <= hole.position.z && z2 >= hz2)
462	{
463		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 76));
464		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 77));
465		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 78));
466	}
467	else if
468		(b.position.x <= hole.position.x && x2 < hx2) &&
469		(b.position.y > hole.position.y && y2 < hy2) &&
470		(b.position.z <= hole.position.z && z2 < hz2)
471	{
472		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 79));
473		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 80));
474		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 81));
475		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 82));
476		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 83));
477		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 84));
478		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 85));
479		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 86));
480	}
481	else if
482		(b.position.x <= hole.position.x && x2 < hx2) &&
483		(b.position.y > hole.position.y && y2 < hy2) &&
484		(b.position.z > hole.position.z && z2 >= hz2)
485	{
486		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 87));
487		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 88));
488		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 89));
489		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 90));
490		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 91));
491	}
492	else if
493		(b.position.x <= hole.position.x && x2 < hx2) &&
494		(b.position.y > hole.position.y && y2 < hy2) &&
495		(b.position.z > hole.position.z && z2 < hz2)
496	{
497		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 92));
498		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 93));
499		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 94));
500		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 95));
501		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 96));
502		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 97));
503		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 98));
504		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 99));
505		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 100));
506		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 101));
507	}
508	else if
509		(b.position.x > hole.position.x && x2 >= hx2) &&
510		(b.position.y <= hole.position.y && y2 >= hy2) &&
511		(b.position.z <= hole.position.z && z2 >= hz2)
512	{
513		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 102));
514	}
515	else if
516		(b.position.x > hole.position.x && x2 >= hx2) &&
517		(b.position.y <= hole.position.y && y2 >= hy2) &&
518		(b.position.z <= hole.position.z && z2 < hz2)
519	{
520		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 103));
521		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 104));
522	}
523	else if
524		(b.position.x > hole.position.x && x2 >= hx2) &&
525		(b.position.y <= hole.position.y && y2 >= hy2) &&
526		(b.position.z > hole.position.z && z2 >= hz2)
527	{
528		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 105));
529		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 106));
530	}
531	else if
532		(b.position.x > hole.position.x && x2 >= hx2) &&
533		(b.position.y <= hole.position.y && y2 >= hy2) &&
534		(b.position.z > hole.position.z && z2 < hz2)
535	{
536		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 107));
537		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 108));
538		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 109));
539	}
540	else if
541		(b.position.x > hole.position.x && x2 >= hx2) &&
542		(b.position.y <= hole.position.y && y2 < hy2) &&
543		(b.position.z <= hole.position.z && z2 >= hz2)
544	{
545		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 110));
546		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 111));
547	}
548	else if
549		(b.position.x > hole.position.x && x2 >= hx2) &&
550		(b.position.y <= hole.position.y && y2 < hy2) &&
551		(b.position.z <= hole.position.z && z2 < hz2)
552	{
553		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 112));
554		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 113));
555		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 114));
556		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 115));
557	}
558	else if
559		(b.position.x > hole.position.x && x2 >= hx2) &&
560		(b.position.y <= hole.position.y && y2 < hy2) &&
561		(b.position.z > hole.position.z && z2 >= hz2)
562	{
563		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 116));
564		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 117));
565		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 118));
566		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 119));
567	}
568	else if
569		(b.position.x > hole.position.x && x2 >= hx2) &&
570		(b.position.y <= hole.position.y && y2 < hy2) &&
571		(b.position.z > hole.position.z && z2 < hz2)
572	{
573		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 120));
574		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 121));
575		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 122));
576		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 123));
577		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 124));
578	}
579	else if
580		(b.position.x > hole.position.x && x2 >= hx2) &&
581		(b.position.y > hole.position.y && y2 >= hy2) &&
582		(b.position.z <= hole.position.z && z2 >= hz2)
583	{
584		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 125));
585		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 126));
586	}
587	else if
588		(b.position.x > hole.position.x && x2 >= hx2) &&
589		(b.position.y > hole.position.y && y2 >= hy2) &&
590		(b.position.z <= hole.position.z && z2 < hz2)
591	{
592		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 127));
593		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 128));
594		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 129));
595		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 130));
596	}
597	else if
598		(b.position.x > hole.position.x && x2 >= hx2) &&
599		(b.position.y > hole.position.y && y2 >= hy2) &&
600		(b.position.z > hole.position.z && z2 >= hz2)
601	{
602		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 131));
603		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 132));
604		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 133));
605	}
606	else if
607		(b.position.x > hole.position.x && x2 >= hx2) &&
608		(b.position.y > hole.position.y && y2 >= hy2) &&
609		(b.position.z > hole.position.z && z2 < hz2)
610	{
611		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 134));
612		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 135));
613		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 136));
614		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 137));
615		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 138));
616	}
617	else if
618		(b.position.x > hole.position.x && x2 >= hx2) &&
619		(b.position.y > hole.position.y && y2 < hy2) &&
620		(b.position.z <= hole.position.z && z2 >= hz2)
621	{
622		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 139));
623		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 140));
624		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 141));
625	}
626	else if
627		(b.position.x > hole.position.x && x2 >= hx2) &&
628		(b.position.y > hole.position.y && y2 < hy2) &&
629		(b.position.z <= hole.position.z && z2 < hz2)
630	{
631		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 142));
632		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 143));
633		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 144));
634		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 145));
635		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 146));
636	}
637	else if
638		(b.position.x > hole.position.x && x2 >= hx2) &&
639		(b.position.y > hole.position.y && y2 < hy2) &&
640		(b.position.z > hole.position.z && z2 >= hz2)
641	{
642		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 147));
643		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 148));
644		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 149));
645		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 150));
646		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 151));
647	}
648	else if
649		(b.position.x > hole.position.x && x2 >= hx2) &&
650		(b.position.y > hole.position.y && y2 < hy2) &&
651		(b.position.z > hole.position.z && z2 < hz2)
652	{
653		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 152));
654		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 153));
655		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 154));
656		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 155));
657		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 156));
658		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 157));
659		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 158));
660	}
661	else if
662		(b.position.x > hole.position.x && x2 < hx2) &&
663		(b.position.y <= hole.position.y && y2 >= hy2) &&
664		(b.position.z <= hole.position.z && z2 >= hz2)
665	{
666		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 159));
667		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 160));
668	}
669	else if
670		(b.position.x > hole.position.x && x2 < hx2) &&
671		(b.position.y <= hole.position.y && y2 >= hy2) &&
672		(b.position.z <= hole.position.z && z2 < hz2)
673	{
674		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 161));
675		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 162));
676		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 163));
677	}
678	else if
679		(b.position.x > hole.position.x && x2 < hx2) &&
680		(b.position.y <= hole.position.y && y2 >= hy2) &&
681		(b.position.z > hole.position.z && z2 >= hz2)
682	{
683		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 164));
684		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 165));
685		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 166));
686	}
687	else if
688		(b.position.x > hole.position.x && x2 < hx2) &&
689		(b.position.y <= hole.position.y && y2 >= hy2) &&
690		(b.position.z > hole.position.z && z2 < hz2)
691	{
692		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 167));
693		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 168));
694		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 169));
695		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 170));
696	}
697	else if
698		(b.position.x > hole.position.x && x2 < hx2) &&
699		(b.position.y <= hole.position.y && y2 < hy2) &&
700		(b.position.z <= hole.position.z && z2 >= hz2)
701	{
702		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 171));
703		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 172));
704		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 173));
705	}
706	else if
707		(b.position.x > hole.position.x && x2 < hx2) &&
708		(b.position.y <= hole.position.y && y2 < hy2) &&
709		(b.position.z <= hole.position.z && z2 < hz2)
710	{
711		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 174));
712		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 175));
713		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 176));
714		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 177));
715		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 178));
716		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 179));
717		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 180));
718		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 181));
719	}
720	else if
721		(b.position.x > hole.position.x && x2 < hx2) &&
722		(b.position.y <= hole.position.y && y2 < hy2) &&
723		(b.position.z > hole.position.z && z2 >= hz2)
724	{
725		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 182));
726		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 183));
727		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 184));
728		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 185));
729		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 186));
730	}
731	else if
732		(b.position.x > hole.position.x && x2 < hx2) &&
733		(b.position.y <= hole.position.y && y2 < hy2) &&
734		(b.position.z > hole.position.z && z2 < hz2)
735	{
736		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 187));
737		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 188));
738		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 189));
739		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 190));
740		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 191));
741		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 192));
742		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 193));
743		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 194));
744		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 195));
745		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 196));
746	}
747	else if
748		(b.position.x > hole.position.x && x2 < hx2) &&
749		(b.position.y > hole.position.y && y2 >= hy2) &&
750		(b.position.z <= hole.position.z && z2 >= hz2)
751	{
752		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 197));
753		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 198));
754		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 199));
755	}
756	else if
757		(b.position.x > hole.position.x && x2 < hx2) &&
758		(b.position.y > hole.position.y && y2 >= hy2) &&
759		(b.position.z <= hole.position.z && z2 < hz2)
760	{
761		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 200));
762		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 201));
763		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 202));
764		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 203));
765		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 204));
766		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 205));
767	}
768	else if
769		(b.position.x > hole.position.x && x2 < hx2) &&
770		(b.position.y > hole.position.y && y2 >= hy2) &&
771		(b.position.z > hole.position.z && z2 >= hz2)
772	{
773		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 206));
774		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 207));
775		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 208));
776		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 209));
777		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 210));
778	}
779	else if
780		(b.position.x > hole.position.x && x2 < hx2) &&
781		(b.position.y > hole.position.y && y2 >= hy2) &&
782		(b.position.z > hole.position.z && z2 < hz2)
783	{
784		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 211));
785		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 212));
786		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 213));
787		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 214));
788		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 215));
789		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 216));
790		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 217));
791	}
792	else if
793		(b.position.x > hole.position.x && x2 < hx2) &&
794		(b.position.y > hole.position.y && y2 < hy2) &&
795		(b.position.z <= hole.position.z && z2 >= hz2)
796	{
797		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 218));
798		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 219));
799		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 220));
800		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 221));
801	}
802	else if
803		(b.position.x > hole.position.x && x2 < hx2) &&
804		(b.position.y > hole.position.y && y2 < hy2) &&
805		(b.position.z <= hole.position.z && z2 < hz2)
806	{
807		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 222));
808		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 223));
809		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 224));
810		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 225));
811		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 226));
812		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 227));
813		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 228));
814		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 229));
815		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 230));
816		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 231));
817	}
818	else if
819		(b.position.x > hole.position.x && x2 < hx2) &&
820		(b.position.y > hole.position.y && y2 < hy2) &&
821		(b.position.z > hole.position.z && z2 >= hz2)
822	{
823		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 232));
824		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 233));
825		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 234));
826		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 235));
827		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 236));
828		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 237));
829		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 238));
830	}
831	else if
832		(b.position.x > hole.position.x && x2 < hx2) &&
833		(b.position.y > hole.position.y && y2 < hy2) &&
834		(b.position.z > hole.position.z && z2 < hz2)
835	{
836		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 239));
837		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,b.position.x-hole.position.x,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 240));
838		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,hy2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 241));
839		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,hz2-hole.position.z, *next_hole_id, 242));
840		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,y2-hole.position.y,b.position.z-hole.position.z, *next_hole_id, 243));
841		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,hole.position.z,hx2-hole.position.x,b.position.y-hole.position.y,z2-hole.position.z, *next_hole_id, 244));
842		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,hy2-hole.position.y,hz2-z2, *next_hole_id, 245));
843		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,hole.position.y,z2,hx2-hole.position.x,y2-hole.position.y,hz2-z2, *next_hole_id, 246));
844		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,hz2-hole.position.z, *next_hole_id, 247));
845		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(hole.position.x,y2,hole.position.z,hx2-hole.position.x,hy2-y2,z2-hole.position.z, *next_hole_id, 248));
846		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,hz2-hole.position.z, *next_hole_id, 249));
847		*next_hole_id += 1; new_holes.push(Box3D::from_xyz_whl(x2,hole.position.y,hole.position.z,hx2-x2,hy2-hole.position.y,z2-hole.position.z, *next_hole_id, 250));
848	}
849
850	for new_hole in new_holes {
851		holes.insert(new_hole);
852	}
853}
854
855fn update_holes(b: &mut Box3D, holes: &mut HashSetFnv<Box3D>, mut next_hole_id: usize)
856-> usize
857{
858	// Cut holes
859	let mut new_holes = HashSetFnv::<Box3D>::default();
860
861	for hole in holes.iter() {
862		// If the Current Box3D overlaps with a hole, we break the hole into new holes
863		if b.intersects(hole) {
864			cut(b, hole, &mut new_holes, &mut next_hole_id);
865		} else if !hole.is_covered_among(&new_holes) {
866			new_holes.insert(*hole);
867		}
868	}
869
870	*holes = new_holes;
871
872	next_hole_id
873}
874
875fn get_new_w(hole: &Box3D, b: &Box3D) -> u64 {
876	hole.position.x + b.size.x
877}
878fn get_new_h(hole: &Box3D, b: &Box3D) -> u64 {
879	hole.position.y + b.size.y
880}
881fn get_new_l(hole: &Box3D, b: &Box3D) -> u64 {
882	hole.position.z + b.size.z
883}
884
885fn is_better_hole(b: &Box3D, hole: &Box3D, best_hole: Option<Box3D>, min_w: u64, min_h: u64, min_l: u64, minimize: Minimize) -> bool
886{
887	if !b.fits_in(hole) { return false; }
888
889	let Some(best_hole) = best_hole else { return true; };
890
891	let hole_perfect = b.size.x == hole.size.x && b.size.y == hole.size.y && b.size.z == hole.size.z;
892	let best_hole_perfect = b.size.x == best_hole.size.x && b.size.y == best_hole.size.y && b.size.z == best_hole.size.z;
893
894	// Best hole is a perfect fit ...
895	if best_hole_perfect && !hole_perfect { return false; }
896
897	// Hole is a perfect fit !
898	if hole_perfect && !best_hole_perfect { return true; }
899
900	let current_w = if minimize.0 { get_new_w(hole, b) } else { 0 };
901	let current_h = if minimize.1 { get_new_h(hole, b) } else { 0 };
902	let current_l = if minimize.2 { get_new_l(hole, b) } else { 0 };
903
904	match minimize {
905		// Minimize Width
906		(true, false, false) => {
907			(current_w, hole.position.x, hole.position.y, hole.position.z, hole.size.x, hole.size.y, hole.size.z, hole.id) <
908			(min_w, best_hole.position.x, best_hole.position.y, best_hole.position.z, best_hole.size.x, best_hole.size.y, best_hole.size.z, best_hole.id)
909		}
910		// Minimize Height
911		(false, true, false) => {
912			(current_h, hole.position.y, hole.position.x, hole.position.z, hole.size.y, hole.size.x, hole.size.z, hole.id) <
913			(min_h, best_hole.position.y, best_hole.position.x, best_hole.position.z, best_hole.size.y, best_hole.size.x, best_hole.size.z, best_hole.id)
914		}
915		// Minimize Length
916		(false, false, true) => {
917			(current_l, hole.position.z, hole.position.x, hole.position.y, hole.size.z, hole.size.x, hole.size.y, hole.id) <
918			(min_l, best_hole.position.z, best_hole.position.x, best_hole.position.y, best_hole.size.z, best_hole.size.x, best_hole.size.y, best_hole.id)
919		}
920		// Minimize Width & Height
921		(true, true, false) => {
922			(current_w.max(current_h), hole.position.x.max(hole.position.y), hole.position.z, hole.size.x.max(hole.size.y), hole.size.z, hole.id) <
923			(min_w.max(min_h), best_hole.position.x.max(best_hole.position.y), best_hole.position.z, best_hole.size.x.max(best_hole.size.y), best_hole.size.z, best_hole.id)
924		}
925		// Minimize Width & Length
926		(true, false, true) => {
927			(current_w.max(current_l), hole.position.x.max(hole.position.z), hole.position.y, hole.size.x.max(hole.size.z), hole.size.y, hole.id) <
928			(min_w.max(min_l), best_hole.position.x.max(best_hole.position.z), best_hole.position.y, best_hole.size.x.max(best_hole.size.z), best_hole.size.y, best_hole.id)
929		}
930		// Minimize Height & Length
931		(false, true, true) => {
932			(current_h.max(current_l), hole.position.y.max(hole.position.z), hole.position.x, hole.size.y.max(hole.size.z), hole.size.x, hole.id) <
933			(min_h.max(min_l), best_hole.position.y.max(best_hole.position.z), best_hole.position.x, best_hole.size.y.max(best_hole.size.z), best_hole.size.x, best_hole.id)
934		}
935		// Minimize all three
936		(true, true, true) => {
937			(current_w.max(current_h).max(current_l), hole.position.x.max(hole.position.y).max(hole.position.z), hole.size.x.max(hole.size.y).max(hole.size.z), hole.id) <
938			(min_w.max(min_h).max(min_l), best_hole.position.x.max(best_hole.position.y).max(best_hole.position.z), best_hole.size.x.max(best_hole.size.y).max(best_hole.size.z), best_hole.id)
939		}
940		// No minimization, use a default Bottom-Left-Front heuristic
941		(false, false, false) => {
942			(hole.position.y, hole.position.x, hole.position.z, hole.id) <
943			(best_hole.position.y, best_hole.position.x, best_hole.position.z, best_hole.id)
944		}
945	}
946}
947
948fn get_best_hole(b: &Box3D, holes: &HashSetFnv<Box3D>, do_rotations: bool, minimize: Minimize) -> (Box3D, Option<Box3D>)
949{
950	let mut new_box = *b;
951	let mut best_hole: Option<Box3D> = None;
952
953	let mut min_w = u64::MAX;
954	let mut min_h = u64::MAX;
955	let mut min_l = u64::MAX;
956
957	let rotations_to_check = if do_rotations { b.get_rotations() } else { vec![*b] };
958
959	for hole in holes.iter() {
960		for rotation in &rotations_to_check {
961			if !rotation.fits_in(hole) {
962				continue;
963			}
964
965			if is_better_hole(rotation, hole, best_hole, min_w, min_h, min_l, minimize) {
966				new_box = *rotation;
967				min_w = get_new_w(hole, rotation);
968				min_h = get_new_h(hole, rotation);
969				min_l = get_new_l(hole, rotation);
970				best_hole = Some(*hole);
971			}
972		}
973	}
974
975	(new_box, best_hole)
976}