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];
169 res += self.size[Space::axis_idx(Axis::X)][xcur] / 2;
173 res += self.size[Space::axis_idx(Axis::Y)][y];
175 res += self.size[Space::axis_idx(Axis::Y)][ycur] / 2;
179 res += self.size[Space::axis_idx(Axis::Z)][z];
181 res += self.size[Space::axis_idx(Axis::Z)][zcur] / 2;
188 pub fn row_size(&self, a: Axis) -> usize {
189 self.size[Space::axis_idx(a)].iter()
190 .fold(0, |row, &s| row + s)
194 pub fn get_edge_size(&self, ((x, y, z), a): Edge) -> usize {
195 self.size[Space::axis_idx(a)][match a {
202 pub fn set_current_face_color_if_any(&mut self, c: FaceColor) {
204 Pos::E(_) => panic!("current is not a face"),
205 Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
206 Some(ref mut f) => f[Space::ori_idx(o)] = Some(c),
207 None => panic!("no face here"),
212 fn edge_size_no_change(&mut self, ((x, y, z), a): Edge, new_size: usize) {
213 let size = &mut self.size[Space::axis_idx(a)][match a {
218 if *size != new_size {
224 pub fn edge_size(&mut self, e: Edge, new_size: usize) {
225 self.edge_size_no_change(e, new_size);
226 self.change = Change::Size(e, new_size);
229 pub fn inc_size(&mut self) {
232 let size = self.get_edge_size(e);
233 if size < usize::MAX {
234 self.edge_size(e, size + 1);
237 Pos::F(_) => panic!("resize on a face"),
241 pub fn dec_size(&mut self) {
244 let size = self.get_edge_size(e);
246 self.edge_size(e, size - 1);
249 Pos::F(_) => panic!("resize on a face"),
253 fn face_edges(&self, ((x, y, z), o): Face) -> Vec<Edge> {
254 let mut edges = Vec::new();
257 edges.push(((x, y, z), Axis::X));
258 edges.push(((x, y, z), Axis::Y));
259 if x < SPACE_SIZE-1 {
260 edges.push(((x+1, y, z), Axis::Y));
263 edges.push(((x, y-1, z), Axis::X));
267 edges.push(((x, y, z), Axis::X));
268 edges.push(((x, y, z), Axis::Z));
269 if x < SPACE_SIZE-1 {
270 edges.push(((x+1, y, z), Axis::Z));
272 if z < SPACE_SIZE-1 {
273 edges.push(((x, y, z+1), Axis::X));
277 edges.push(((x, y, z), Axis::Y));
278 edges.push(((x, y, z), Axis::Z));
280 edges.push(((x, y-1, z), Axis::Z));
282 if z < SPACE_SIZE-1 {
283 edges.push(((x, y, z+1), Axis::Y));
291 fn add_empty_node(&mut self, (x, y, z): Coord) {
292 assert!(!self.is_node((x, y, z)));
293 self.faces[x][y][z] = Some([None; NOF_DIM]);
294 self.change = Change::Space;
297 fn adj_available_faces(&self, e: Edge) -> Vec<Face> {
298 Space::adj_faces(e).iter()
299 .filter_map(|&adj_f| if self.is_face(adj_f) {
303 }).collect::<Vec<_>>()
306 fn adj_existing_faces(&self, e: Edge) -> Vec<Face> {
307 Space::adj_faces(e).iter()
308 .filter_map(|&adj_f| if self.is_face(adj_f) {
312 }).collect::<Vec<_>>()
315 pub fn dec_pos(&mut self) {
316 let tmp = match self.current {
317 Pos::E(((mut x, mut y, mut z), a)) => {
325 Pos::F(((mut x, mut y, mut z), o)) => {
334 if self.is_node(tmp) {
335 self.change = Change::Current;
337 Pos::E((ref mut n, _)) => *n = tmp,
338 Pos::F((ref mut n, _)) => *n = tmp,
343 pub fn inc_pos(&mut self) {
344 let tmp = match self.current {
345 Pos::E(((mut x, mut y, mut z), a)) => {
353 Pos::F(((mut x, mut y, mut z), o)) => {
362 if self.is_node(tmp) {
363 self.change = Change::Current;
365 Pos::E((ref mut n, _)) => *n = tmp,
366 Pos::F((ref mut n, _)) => *n = tmp,
371 pub fn inc_pos2(&mut self) {
372 let tmp = match self.current {
373 Pos::E(_) => panic!(),
374 Pos::F(((mut x, mut y, mut z), o)) => {
383 if self.is_node(tmp) {
384 self.change = Change::Current;
387 Pos::F((ref mut n, _)) => *n = tmp,
392 pub fn dec_pos2(&mut self) {
393 let tmp = match self.current {
394 Pos::E(_) => panic!(),
395 Pos::F(((mut x, mut y, mut z), o)) => {
404 if self.is_node(tmp) {
405 self.change = Change::Current;
408 Pos::F((ref mut n, _)) => *n = tmp,
413 pub fn inc_pos3(&mut self) {
414 let tmp = match self.current {
415 Pos::E(_) => panic!(),
416 Pos::F(((mut x, mut y, mut z), o)) => {
425 if self.is_node(tmp) {
426 self.change = Change::Current;
429 Pos::F((ref mut n, _)) => *n = tmp,
434 pub fn dec_pos3(&mut self) {
435 let tmp = match self.current {
436 Pos::E(_) => panic!(),
437 Pos::F(((mut x, mut y, mut z), o)) => {
446 if self.is_node(tmp) {
447 self.change = Change::Current;
450 Pos::F((ref mut n, _)) => *n = tmp,
455 pub fn rotate(&mut self) {
456 self.change = Change::Current;
458 Pos::E((_, ref mut a)) => match *a {
459 Axis::X => *a = Axis::Y,
460 Axis::Y => *a = Axis::Z,
461 Axis::Z => *a = Axis::X,
463 Pos::F((_, ref mut o)) => match *o {
464 Ori::Top => *o = Ori::Back,
465 Ori::Back => *o = Ori::Side,
466 Ori::Side => *o = Ori::Top,
471 pub fn set_pos_kind(&mut self, pk: PosKind) {
473 PosKind::Face => if let Pos::E((c, a)) = self.current {
474 self.change = Change::Current;
475 self.current = Pos::F((c, match a {
476 Axis::X => Ori::Side,
477 Axis::Y => Ori::Back,
481 PosKind::Edge => if let Pos::F((c, o)) = self.current {
482 self.change = Change::Current;
483 self.current = Pos::E((c, match o {
484 Ori::Side => Axis::X,
485 Ori::Back => Axis::Y,
492 fn all_nodes_coord(&self) -> Vec<Coord> {
493 let mut nodes = Vec::new();
494 for x in 0..self.faces.len() {
495 for y in 0..self.faces[x].len() {
496 for z in 0..self.faces[x][y].len() {
497 if self.is_node((x, y, z)) {
498 nodes.push((x, y, z));
506 fn connecting_edge(&self, f1: Face, f2: Face) -> Option<Edge> {
507 for e1 in self.face_edges(f1) {
508 for e2 in self.face_edges(f2) {
517 fn all_faces(&self) -> Vec<Face> {
518 let mut faces = Vec::new();
519 for n in self.all_nodes_coord() {
520 for &o in [Ori::Top, Ori::Side, Ori::Back].iter() {
521 if self.is_face((n, o)) {
529 fn faces_map(&self) -> Vec<(Face, Vec<Face>)> {
530 let mut map = Vec::new();
531 for f in self.all_faces() {
532 let mut adj_faces = Vec::new();
533 for &e in self.face_edges(f).iter() {
534 for &adj_f in self.adj_existing_faces(e).iter() {
536 adj_faces.push(adj_f);
540 map.push((f, adj_faces));
546 fn face_dot_label_fmt(((x, y, z), o): Face, s: &str) -> String {
547 format!("f{0}_{1}_{2}_{3} [label=\"{0} {1} {2} {3}\" {4}]",
548 x, y, z, Space::ori_idx(o), s)
552 fn face_dot_fmt(((x, y, z), o): Face) -> String {
553 format!("f{}_{}_{}_{}", x, y, z, Space::ori_idx(o))
556 fn dot_face_pairs(&self) -> Vec<(Face, Face)> {
557 let mut pairs = Vec::new();
559 let fmap = self.faces_map();
560 let (f_tx, f_rx): (Sender<(Face, Face)>, Receiver<(Face, Face)>) = mpsc::channel();
561 let mut nof_pairs = 0;
562 for map_chunk in fmap.chunks((fmap.len() / NOF_THREADS) + 1) {
563 let thread_f_tx = f_tx.clone();
564 let thread_mc = map_chunk.iter().map(|x| {
565 nof_pairs += x.1.len();
567 }).collect::<Vec<(Face, Vec<Face>)>>();
568 thread::spawn(move || {
569 for (f, adj_fs) in thread_mc {
570 for adj_f in adj_fs {
571 thread_f_tx.send((f, adj_f)).unwrap();
576 for _ in 0..nof_pairs {
577 pairs.push(f_rx.recv().unwrap());
581 pairs.iter().filter_map(|&(a1, b1)| {
583 if !pairs.iter().take(i-1)
584 .any(|&(b2, a2)| a1 == a2 && b1 == b2) {
589 }).collect::<Vec<(Face, Face)>>()
592 fn dot_face_decls(&self) -> String {
593 let mut decls = String::new();
595 let faces = self.all_faces();
596 let (s_tx, s_rx): (Sender<String>, Receiver<String>) = mpsc::channel();
597 for faces_chunk in faces.chunks((faces.len() / NOF_THREADS) + 1) {
598 let thread_s_tx = s_tx.clone();
599 let thread_fs = faces_chunk.iter().map(|x| x.clone()).collect::<Vec<Face>>();
600 let current = self.current;
601 thread::spawn(move || {
603 thread_s_tx.send(format!(" {};\n", Space::face_dot_label_fmt(f,
604 if Pos::F(f) == current { "color=red" } else { "" })))
609 for _ in 0..faces.len() {
610 decls.push_str(&s_rx.recv().unwrap());
616 pub fn dot_graph_code(&self) -> String {
617 let mut code = String::from("graph {\n");
618 code.push_str(&self.dot_face_decls());
619 for (a, b) in self.dot_face_pairs() {
620 code.push_str(&format!(" {} -- {}{};\n",
621 Space::face_dot_fmt(a),
622 Space::face_dot_fmt(b),
623 if let Some(e) = self.connecting_edge(a, b) {
624 if Pos::E(e) == self.current {
634 fn add_empty_node_if_none(&mut self, n: Coord) {
635 if !self.is_node(n) {
636 self.add_empty_node(n);
640 fn set_face(&mut self, ((x, y, z), o): Face, v: Option<FaceColor>) {
641 match self.faces[x][y][z] {
643 if f[Space::ori_idx(o)] != v {
644 self.change = Change::Space;
646 f[Space::ori_idx(o)] = v;
648 None => panic!("there is no node here"),
652 fn face_adj_available_faces(&self, f: Face) -> Vec<Face> {
653 let mut faces = Vec::new();
654 for e in self.face_edges(f) {
655 for adj_f in self.adj_available_faces(e) {
664 fn suround_with_nodes(&mut self, (n, o): Face) {
665 assert!(self.is_node(n));
666 for (nf, _) in self.face_adj_available_faces((n, o)) {
667 self.add_empty_node_if_none(nf);
672 pub fn add_face(&mut self, f: Face) {
673 self.suround_with_nodes(f);
674 self.set_face(f, Some((1.0, 1.0, 1.0)));
678 pub fn remove_face(&mut self, f: Face) {
679 assert!(self.is_face(f));
680 self.set_face(f, None);
683 pub fn set_current_face_if_none(&mut self) {
685 Pos::F(f) => if !self.is_face(f) { self.add_face(f) },
691 impl Clone for Space {
692 fn clone(&self) -> Space {
696 current: self.current,
716 fn new() -> History {
724 fn add(&mut self, s: Save) {
725 if self.saves.len() > self.id {
726 while self.saves.len() > self.id {
734 pub fn has_prev(&self) -> bool {
738 pub fn has_next(&self) -> bool {
739 self.saves.len() > self.id
742 fn prev(&mut self) -> Save {
743 assert!(self.has_prev());
746 self.saves[self.id-1].clone()
749 fn next(&mut self) -> Save {
750 assert!(self.has_next());
753 self.saves[self.id-1].clone()
756 fn current(&self) -> Option<&Save> {
760 Some(&self.saves[self.id-1])
764 fn replace_current(&mut self, s: Save) {
765 assert!(self.id != 0);
766 self.saves[self.id-1] = s;
772 pub history: History,
776 pub fn new() -> Data {
777 Data { space: Space::new(), history: History::new() }
780 fn save_to_add(&self) -> Option<Save> {
781 match self.space.change {
783 let mut space = self.space.clone();
784 space.change = Change::None;
785 Some(Save::Space(space))
787 Change::Current => Some(Save::Current(self.space.current)),
788 Change::Size(e, s) => Some(Save::Size(e, s)),
789 Change::None => None,
793 pub fn save_if_changed(&mut self) {
794 match self.save_to_add() {
795 Some(Save::Size(e, s)) =>
796 match self.history.current() {
797 Some(&Save::Size(e, _)) =>
798 self.history.replace_current(Save::Size(e, s)),
799 _ => self.history.add(Save::Size(e, s)),
801 Some(s) => self.history.add(s),
804 self.space.change = Change::None;
807 pub fn load_prev(&mut self) {
808 match self.history.prev() {
809 Save::Current(c) => self.space.current = c,
810 Save::Space(s) => self.space = s,
811 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
815 pub fn load_next(&mut self) {
816 match self.history.next() {
817 Save::Current(c) => self.space.current = c,
818 Save::Space(s) => self.space = s,
819 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
823 pub fn load_prev_if_any(&mut self) {
824 if self.history.has_prev() {
829 pub fn load_next_if_any(&mut self) {
830 if self.history.has_next() {