3 use std::sync::mpsc::{Sender, Receiver};
7 const SPACE_SIZE: usize = 21;
8 const NOF_DIM: usize = 3;
9 const DEFAULT_FACE_SIZE: usize = 64;
10 const NOF_THREADS: usize = 4;
12 #[derive(Clone, Copy, PartialEq, Debug)]
19 #[derive(Clone, Copy, PartialEq, Debug)]
26 #[derive(Clone, Copy, PartialEq, Debug)]
32 #[derive(Clone, Copy, PartialEq, Debug)]
40 #[derive(Clone, Copy, PartialEq, Debug)]
46 pub type Coord = (usize, usize, usize);
47 pub type Edge = (Coord, Axis);
48 pub type Face = (Coord, Ori);
49 pub type FaceColor = (f32, f32, f32);
50 pub type Surface = [Option<FaceColor>; NOF_DIM];
53 pub size: [[usize; SPACE_SIZE]; NOF_DIM],
54 pub faces: [[[Option<Surface>; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
61 let mid = SPACE_SIZE / 2;
62 let current_node = (mid, mid, mid);
64 size: [[DEFAULT_FACE_SIZE; SPACE_SIZE]; NOF_DIM],
65 faces: [[[None; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
66 current: Pos::E((current_node, Axis::X)),
69 tmp.add_empty_node(current_node);
70 tmp.add_face((current_node, Ori::Top));
75 pub fn axis_idx(a: Axis) -> usize {
84 pub fn ori_idx(o: Ori) -> usize {
92 fn adj_faces(((x, y, z), a): Edge) -> Vec<Face> {
93 let mut faces = Vec::new();
96 faces.push(((x, y, z), Ori::Top));
97 faces.push(((x, y, z), Ori::Back));
98 if y < (SPACE_SIZE - 1) {
99 faces.push(((x, y+1, z), Ori::Top));
102 faces.push(((x, y, z-1), Ori::Back));
106 faces.push(((x, y, z), Ori::Top));
107 faces.push(((x, y, z), Ori::Side));
109 faces.push(((x-1, y, z), Ori::Top));
112 faces.push(((x, y, z-1), Ori::Side));
116 faces.push(((x, y, z), Ori::Back));
117 faces.push(((x, y, z), Ori::Side));
119 faces.push(((x-1, y, z), Ori::Back));
121 if y < (SPACE_SIZE - 1) {
122 faces.push(((x, y+1, z), Ori::Side));
130 fn is_node(&self, (x, y, z): Coord) -> bool {
134 if let Some(_) = self.faces[x][y][z] {
145 fn is_face(&self, ((x, y, z), o): Face) -> bool {
146 self.is_node((x, y, z))
147 && match self.faces[x][y][z] {
148 Some(faces) => faces[Space::ori_idx(o)] != None,
154 pub fn current_node_coord(&self) -> Coord {
161 pub fn row_size_before_current(&self, a: Axis) -> usize {
162 let (xcur, ycur, zcur) = self.current_node_coord();
167 res += self.size[Space::axis_idx(Axis::X)][x];
172 res += self.size[Space::axis_idx(Axis::Y)][y];
177 res += self.size[Space::axis_idx(Axis::Z)][z];
185 pub fn row_size(&self, a: Axis) -> usize {
186 self.size[Space::axis_idx(a)].iter()
187 .fold(0, |row, &s| row + s)
191 pub fn get_edge_size(&self, ((x, y, z), a): Edge) -> usize {
192 self.size[Space::axis_idx(a)][match a {
199 pub fn set_current_face_color_if_any(&mut self, c: FaceColor) {
201 Pos::E(_) => panic!("current is not a face"),
202 Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
203 Some(ref mut f) => f[Space::ori_idx(o)] = Some(c),
204 None => panic!("no face here"),
209 fn edge_size_no_change(&mut self, ((x, y, z), a): Edge, new_size: usize) {
210 let size = &mut self.size[Space::axis_idx(a)][match a {
215 if *size != new_size {
221 pub fn edge_size(&mut self, e: Edge, new_size: usize) {
222 self.edge_size_no_change(e, new_size);
223 self.change = Change::Size(e, new_size);
226 pub fn inc_size(&mut self) {
229 let size = self.get_edge_size(e);
230 if size < usize::MAX {
231 self.edge_size(e, size + 1);
234 Pos::F(_) => panic!("resize on a face"),
238 pub fn dec_size(&mut self) {
241 let size = self.get_edge_size(e);
243 self.edge_size(e, size - 1);
246 Pos::F(_) => panic!("resize on a face"),
250 fn face_edges(&self, ((x, y, z), o): Face) -> Vec<Edge> {
251 let mut edges = Vec::new();
254 edges.push(((x, y, z), Axis::X));
255 edges.push(((x, y, z), Axis::Y));
256 if x < SPACE_SIZE-1 {
257 edges.push(((x+1, y, z), Axis::Y));
260 edges.push(((x, y-1, z), Axis::X));
264 edges.push(((x, y, z), Axis::X));
265 edges.push(((x, y, z), Axis::Z));
266 if x < SPACE_SIZE-1 {
267 edges.push(((x+1, y, z), Axis::Z));
269 if z < SPACE_SIZE-1 {
270 edges.push(((x, y, z+1), Axis::X));
274 edges.push(((x, y, z), Axis::Y));
275 edges.push(((x, y, z), Axis::Z));
277 edges.push(((x, y-1, z), Axis::Z));
279 if z < SPACE_SIZE-1 {
280 edges.push(((x, y, z+1), Axis::Y));
288 fn add_empty_node(&mut self, (x, y, z): Coord) {
289 assert!(!self.is_node((x, y, z)));
290 self.faces[x][y][z] = Some([None; NOF_DIM]);
291 self.change = Change::Space;
294 fn adj_available_faces(&self, e: Edge) -> Vec<Face> {
295 Space::adj_faces(e).iter()
296 .filter_map(|&adj_f| if self.is_face(adj_f) {
300 }).collect::<Vec<_>>()
303 fn adj_existing_faces(&self, e: Edge) -> Vec<Face> {
304 Space::adj_faces(e).iter()
305 .filter_map(|&adj_f| if self.is_face(adj_f) {
309 }).collect::<Vec<_>>()
312 pub fn dec_pos(&mut self) {
313 let tmp = match self.current {
314 Pos::E(((mut x, mut y, mut z), a)) => {
322 Pos::F(((mut x, mut y, mut z), o)) => {
331 if self.is_node(tmp) {
332 self.change = Change::Current;
334 Pos::E((ref mut n, _)) => *n = tmp,
335 Pos::F((ref mut n, _)) => *n = tmp,
340 pub fn inc_pos(&mut self) {
341 let tmp = match self.current {
342 Pos::E(((mut x, mut y, mut z), a)) => {
350 Pos::F(((mut x, mut y, mut z), o)) => {
359 if self.is_node(tmp) {
360 self.change = Change::Current;
362 Pos::E((ref mut n, _)) => *n = tmp,
363 Pos::F((ref mut n, _)) => *n = tmp,
368 pub fn rotate(&mut self) {
369 self.change = Change::Current;
371 Pos::E((_, ref mut a)) => match *a {
372 Axis::X => *a = Axis::Y,
373 Axis::Y => *a = Axis::Z,
374 Axis::Z => *a = Axis::X,
376 Pos::F((_, ref mut o)) => match *o {
377 Ori::Top => *o = Ori::Back,
378 Ori::Back => *o = Ori::Side,
379 Ori::Side => *o = Ori::Top,
384 pub fn set_pos_kind(&mut self, pk: PosKind) {
386 PosKind::Face => if let Pos::E((c, a)) = self.current {
387 self.change = Change::Current;
388 self.current = Pos::F((c, match a {
389 Axis::X => Ori::Side,
390 Axis::Y => Ori::Back,
394 PosKind::Edge => if let Pos::F((c, o)) = self.current {
395 self.change = Change::Current;
396 self.current = Pos::E((c, match o {
397 Ori::Side => Axis::X,
398 Ori::Back => Axis::Y,
405 fn all_nodes_coord(&self) -> Vec<Coord> {
406 let mut nodes = Vec::new();
407 for x in 0..self.faces.len() {
408 for y in 0..self.faces[x].len() {
409 for z in 0..self.faces[x][y].len() {
410 if self.is_node((x, y, z)) {
411 nodes.push((x, y, z));
419 fn connecting_edge(&self, f1: Face, f2: Face) -> Option<Edge> {
420 for e1 in self.face_edges(f1) {
421 for e2 in self.face_edges(f2) {
430 fn all_faces(&self) -> Vec<Face> {
431 let mut faces = Vec::new();
432 for n in self.all_nodes_coord() {
433 for &o in [Ori::Top, Ori::Side, Ori::Back].iter() {
434 if self.is_face((n, o)) {
442 fn faces_map(&self) -> Vec<(Face, Vec<Face>)> {
443 let mut map = Vec::new();
444 for f in self.all_faces() {
445 let mut adj_faces = Vec::new();
446 for &e in self.face_edges(f).iter() {
447 for &adj_f in self.adj_existing_faces(e).iter() {
449 adj_faces.push(adj_f);
453 map.push((f, adj_faces));
459 fn face_dot_label_fmt(((x, y, z), o): Face, s: &str) -> String {
460 format!("f{0}_{1}_{2}_{3} [label=\"{0} {1} {2} {3}\" {4}]",
461 x, y, z, Space::ori_idx(o), s)
465 fn face_dot_fmt(((x, y, z), o): Face) -> String {
466 format!("f{}_{}_{}_{}", x, y, z, Space::ori_idx(o))
469 fn dot_face_pairs(&self) -> Vec<(Face, Face)> {
470 let mut pairs = Vec::new();
472 let fmap = self.faces_map();
473 let (f_tx, f_rx): (Sender<(Face, Face)>, Receiver<(Face, Face)>) = mpsc::channel();
474 let mut nof_pairs = 0;
475 for map_chunk in fmap.chunks((fmap.len() / NOF_THREADS) + 1) {
476 let thread_f_tx = f_tx.clone();
477 let thread_mc = map_chunk.iter().map(|x| {
478 nof_pairs += x.1.len();
480 }).collect::<Vec<(Face, Vec<Face>)>>();
481 thread::spawn(move || {
482 for (f, adj_fs) in thread_mc {
483 for adj_f in adj_fs {
484 thread_f_tx.send((f, adj_f)).unwrap();
489 for _ in 0..nof_pairs {
490 pairs.push(f_rx.recv().unwrap());
494 pairs.iter().filter_map(|&(a1, b1)| {
496 if !pairs.iter().take(i-1)
497 .any(|&(b2, a2)| a1 == a2 && b1 == b2) {
502 }).collect::<Vec<(Face, Face)>>()
505 fn dot_face_decls(&self) -> String {
506 let mut decls = String::new();
508 let faces = self.all_faces();
509 let (s_tx, s_rx): (Sender<String>, Receiver<String>) = mpsc::channel();
510 for faces_chunk in faces.chunks((faces.len() / NOF_THREADS) + 1) {
511 let thread_s_tx = s_tx.clone();
512 let thread_fs = faces_chunk.iter().map(|x| x.clone()).collect::<Vec<Face>>();
513 let current = self.current;
514 thread::spawn(move || {
516 thread_s_tx.send(format!(" {};\n", Space::face_dot_label_fmt(f,
517 if Pos::F(f) == current { "color=red" } else { "" })))
522 for _ in 0..faces.len() {
523 decls.push_str(&s_rx.recv().unwrap());
529 pub fn dot_graph_code(&self) -> String {
530 let mut code = String::from("graph {\n");
531 code.push_str(&self.dot_face_decls());
532 for (a, b) in self.dot_face_pairs() {
533 code.push_str(&format!(" {} -- {}{};\n",
534 Space::face_dot_fmt(a),
535 Space::face_dot_fmt(b),
536 if let Some(e) = self.connecting_edge(a, b) {
537 if Pos::E(e) == self.current {
547 fn add_empty_node_if_none(&mut self, n: Coord) {
548 if !self.is_node(n) {
549 self.add_empty_node(n);
553 fn set_face(&mut self, ((x, y, z), o): Face, v: Option<FaceColor>) {
554 match self.faces[x][y][z] {
556 if f[Space::ori_idx(o)] != v {
557 self.change = Change::Space;
559 f[Space::ori_idx(o)] = v;
561 None => panic!("there is no node here"),
565 fn face_adj_available_faces(&self, f: Face) -> Vec<Face> {
566 let mut faces = Vec::new();
567 for e in self.face_edges(f) {
568 for adj_f in self.adj_available_faces(e) {
577 fn suround_with_nodes(&mut self, (n, o): Face) {
578 assert!(self.is_node(n));
579 for (nf, _) in self.face_adj_available_faces((n, o)) {
580 self.add_empty_node_if_none(nf);
585 pub fn add_face(&mut self, f: Face) {
586 self.suround_with_nodes(f);
587 self.set_face(f, Some((1.0, 1.0, 1.0)));
591 pub fn remove_face(&mut self, f: Face) {
592 assert!(self.is_face(f));
593 self.set_face(f, None);
596 pub fn set_current_face_if_none(&mut self) {
598 Pos::F(f) => if !self.is_face(f) { self.add_face(f) },
604 impl Clone for Space {
605 fn clone(&self) -> Space {
609 current: self.current,
629 fn new() -> History {
637 fn add(&mut self, s: Save) {
638 if self.saves.len() > self.id {
639 while self.saves.len() > self.id {
647 pub fn has_prev(&self) -> bool {
651 pub fn has_next(&self) -> bool {
652 self.saves.len() > self.id
655 fn prev(&mut self) -> Save {
656 assert!(self.has_prev());
659 self.saves[self.id-1].clone()
662 fn next(&mut self) -> Save {
663 assert!(self.has_next());
666 self.saves[self.id-1].clone()
669 fn current(&self) -> Option<&Save> {
673 Some(&self.saves[self.id-1])
677 fn replace_current(&mut self, s: Save) {
678 assert!(self.id != 0);
679 self.saves[self.id-1] = s;
685 pub history: History,
689 pub fn new() -> Data {
690 Data { space: Space::new(), history: History::new() }
693 fn save_to_add(&self) -> Option<Save> {
694 match self.space.change {
696 let mut space = self.space.clone();
697 space.change = Change::None;
698 Some(Save::Space(space))
700 Change::Current => Some(Save::Current(self.space.current)),
701 Change::Size(e, s) => Some(Save::Size(e, s)),
702 Change::None => None,
706 pub fn save_if_changed(&mut self) {
707 match self.save_to_add() {
708 Some(Save::Size(e, s)) =>
709 match self.history.current() {
710 Some(&Save::Size(e, _)) =>
711 self.history.replace_current(Save::Size(e, s)),
712 _ => self.history.add(Save::Size(e, s)),
714 Some(s) => self.history.add(s),
717 self.space.change = Change::None;
720 pub fn load_prev(&mut self) {
721 match self.history.prev() {
722 Save::Current(c) => self.space.current = c,
723 Save::Space(s) => self.space = s,
724 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
728 pub fn load_next(&mut self) {
729 match self.history.next() {
730 Save::Current(c) => self.space.current = c,
731 Save::Space(s) => self.space = s,
732 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
736 pub fn load_prev_if_any(&mut self) {
737 if self.history.has_prev() {
742 pub fn load_next_if_any(&mut self) {
743 if self.history.has_next() {