3 const SPACE_SIZE: usize = 11;
4 const NOF_DIM: usize = 3;
5 const DEFAULT_FACE_SIZE: usize = 64;
7 #[derive(Clone, Copy, PartialEq, Debug)]
14 #[derive(Clone, Copy, PartialEq, Debug)]
21 #[derive(Clone, Copy, PartialEq, Debug)]
27 #[derive(Clone, Copy, PartialEq, Debug)]
35 #[derive(Clone, Copy, PartialEq, Debug)]
41 pub type Coord = (usize, usize, usize);
42 pub type Edge = (Coord, Axis);
43 pub type Face = (Coord, Ori);
44 pub type FaceColor = (f32, f32, f32);
45 pub type Surface = [Option<FaceColor>; NOF_DIM];
48 pub size: [[usize; SPACE_SIZE]; NOF_DIM],
49 pub faces: [[[Option<Surface>; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
56 let mid = SPACE_SIZE / 2;
57 let current_node = (mid, mid, mid);
59 size: [[DEFAULT_FACE_SIZE; SPACE_SIZE]; NOF_DIM],
60 faces: [[[None; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
61 current: Pos::E((current_node, Axis::X)),
64 tmp.add_empty_node(current_node);
65 tmp.add_face((current_node, Ori::Top));
69 pub fn axis_idx(a: Axis) -> usize {
77 pub fn ori_idx(o: Ori) -> usize {
85 fn adj_faces(((x, y, z), a): Edge) -> Vec<Face> {
86 let mut faces = Vec::new();
89 faces.push(((x, y, z), Ori::Top));
90 faces.push(((x, y, z), Ori::Back));
91 if y < (SPACE_SIZE - 1) {
92 faces.push(((x, y+1, z), Ori::Top));
95 faces.push(((x, y, z-1), Ori::Back));
99 faces.push(((x, y, z), Ori::Top));
100 faces.push(((x, y, z), Ori::Side));
102 faces.push(((x-1, y, z), Ori::Top));
105 faces.push(((x, y, z-1), Ori::Side));
109 faces.push(((x, y, z), Ori::Back));
110 faces.push(((x, y, z), Ori::Side));
112 faces.push(((x-1, y, z), Ori::Back));
114 if y < (SPACE_SIZE - 1) {
115 faces.push(((x, y+1, z), Ori::Side));
122 fn is_node(&self, (x, y, z): Coord) -> bool {
126 if let Some(_) = self.faces[x][y][z] {
136 fn is_face(&self, ((x, y, z), o): Face) -> bool {
137 self.is_node((x, y, z))
138 && match self.faces[x][y][z] {
139 Some(faces) => faces[Space::ori_idx(o)] != None,
144 pub fn current_node_coord(&self) -> Coord {
151 pub fn row_size_before_current(&self, a: Axis) -> usize {
152 let (xcur, ycur, zcur) = self.current_node_coord();
157 res += self.size[Space::axis_idx(Axis::X)][x];
162 res += self.size[Space::axis_idx(Axis::Y)][y];
167 res += self.size[Space::axis_idx(Axis::Z)][z];
174 pub fn row_size(&self, a: Axis) -> usize {
175 self.size[Space::axis_idx(a)].iter()
176 .fold(0, |row, &s| row + s)
179 pub fn get_edge_size(&self, ((x, y, z), a): Edge) -> usize {
180 //assert!(self.is_edge(((x, y, z), a)));
181 self.size[Space::axis_idx(a)][match a {
188 pub fn set_current_face_color_if_any(&mut self, c: FaceColor) {
190 Pos::E(_) => panic!("current is not a face"),
191 Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
192 Some(ref mut f) => f[Space::ori_idx(o)] = Some(c),
193 None => panic!("no face here"),
198 fn edge_size_no_change(&mut self, ((x, y, z), a): Edge, new_size: usize) {
199 //assert!(self.is_edge(((x, y, z), a)));
200 let size = &mut self.size[Space::axis_idx(a)][match a {
205 if *size != new_size {
210 pub fn edge_size(&mut self, e: Edge, new_size: usize) {
211 self.edge_size_no_change(e, new_size);
212 self.change = Change::Size(e, new_size);
215 pub fn inc_size(&mut self) {
218 let size = self.get_edge_size(e);
219 if size < usize::MAX {
220 self.edge_size(e, size + 1);
223 Pos::F(_) => panic!("resize on a face"),
227 pub fn dec_size(&mut self) {
230 let size = self.get_edge_size(e);
232 self.edge_size(e, size - 1);
235 Pos::F(_) => panic!("resize on a face"),
239 fn face_edges(&self, ((x, y, z), o): Face) -> Vec<Edge> {
240 let mut edges = Vec::new();
243 edges.push(((x, y, z), Axis::X));
244 edges.push(((x, y, z), Axis::Y));
245 if x < SPACE_SIZE-1 {
246 edges.push(((x+1, y, z), Axis::Y));
249 edges.push(((x, y-1, z), Axis::X));
253 edges.push(((x, y, z), Axis::X));
254 edges.push(((x, y, z), Axis::Z));
255 if x < SPACE_SIZE-1 {
256 edges.push(((x+1, y, z), Axis::Z));
258 if z < SPACE_SIZE-1 {
259 edges.push(((x, y, z+1), Axis::X));
263 edges.push(((x, y, z), Axis::Y));
264 edges.push(((x, y, z), Axis::Z));
266 edges.push(((x, y-1, z), Axis::Z));
268 if z < SPACE_SIZE-1 {
269 edges.push(((x, y, z+1), Axis::Y));
276 fn add_empty_node(&mut self, (x, y, z): Coord) {
277 assert!(!self.is_node((x, y, z)));
278 self.faces[x][y][z] = Some([None; NOF_DIM]);
279 println!("empty node change");
280 self.change = Change::Space;
283 fn adj_available_faces(&self, e: Edge) -> Vec<Face> {
284 Space::adj_faces(e).iter()
285 .filter_map(|&adj_f| if self.is_face(adj_f) {
289 }).collect::<Vec<_>>()
292 fn adj_existing_faces(&self, e: Edge) -> Vec<Face> {
293 Space::adj_faces(e).iter()
294 .filter_map(|&adj_f| if self.is_face(adj_f) {
298 }).collect::<Vec<_>>()
301 pub fn dec_pos(&mut self) {
302 let tmp = match self.current {
303 Pos::E(((mut x, mut y, mut z), a)) => {
311 Pos::F(((mut x, mut y, mut z), o)) => {
320 if self.is_node(tmp) {
321 println!("pos change");
322 self.change = Change::Current;
324 Pos::E((ref mut n, _)) => *n = tmp,
325 Pos::F((ref mut n, _)) => *n = tmp,
330 pub fn inc_pos(&mut self) {
331 let tmp = match self.current {
332 Pos::E(((mut x, mut y, mut z), a)) => {
340 Pos::F(((mut x, mut y, mut z), o)) => {
349 if self.is_node(tmp) {
350 println!("pos change");
351 self.change = Change::Current;
353 Pos::E((ref mut n, _)) => *n = tmp,
354 Pos::F((ref mut n, _)) => *n = tmp,
359 pub fn rotate(&mut self) {
360 println!("rotate change");
361 self.change = Change::Current;
363 Pos::E((_, ref mut a)) => match *a {
364 Axis::X => *a = Axis::Y,
365 Axis::Y => *a = Axis::Z,
366 Axis::Z => *a = Axis::X,
368 Pos::F((_, ref mut o)) => match *o {
369 Ori::Top => *o = Ori::Back,
370 Ori::Back => *o = Ori::Side,
371 Ori::Side => *o = Ori::Top,
376 pub fn set_pos_kind(&mut self, pk: PosKind) {
378 PosKind::Face => if let Pos::E((c, a)) = self.current {
379 self.change = Change::Current;
380 self.current = Pos::F((c, match a {
381 Axis::X => Ori::Side,
382 Axis::Y => Ori::Back,
386 PosKind::Edge => if let Pos::F((c, o)) = self.current {
387 self.change = Change::Current;
388 self.current = Pos::E((c, match o {
389 Ori::Side => Axis::X,
390 Ori::Back => Axis::Y,
397 pub fn switch_pos_type(&mut self) {
398 println!("switch change");
400 Pos::E(_) => self.set_pos_kind(PosKind::Face),
401 Pos::F(_) => self.set_pos_kind(PosKind::Edge),
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));
458 fn face_dot_label_fmt(((x, y, z), o): Face, s: &str) -> String {
459 format!("f{0}_{1}_{2}_{3} [label=\"{0} {1} {2} {3}\" {4}]",
460 x, y, z, Space::ori_idx(o), s)
463 fn face_dot_fmt(((x, y, z), o): Face) -> String {
464 format!("f{}_{}_{}_{}", x, y, z, Space::ori_idx(o))
467 pub fn dot_graph_code(&self) -> String {
468 let mut code = String::from("graph {\n");
469 let mut pairs = Vec::new();
470 for (f, adj_fs) in self.faces_map() {
471 code.push_str(&format!(" {};\n", Space::face_dot_label_fmt(f,
472 if Pos::F(f) == self.current { "color=red" } else { "" })));
473 for adj_f in adj_fs {
474 pairs.push((f, adj_f));
478 let pairs_clean = pairs.iter().filter(|&&(a1, b1)| {
480 !pairs.iter().take(i-1)
481 .any(|&(b2, a2)| a1 == a2 && b1 == b2)
482 }).collect::<Vec<_>>();
483 for &(a, b) in pairs_clean {
484 code.push_str(&format!(" {} -- {} {};\n",
485 Space::face_dot_fmt(a),
486 Space::face_dot_fmt(b),
487 if let Some(e) = self.connecting_edge(a, b) {
488 if Pos::E(e) == self.current {
494 println!("{}", code);
498 fn add_empty_node_if_none(&mut self, n: Coord) {
499 if !self.is_node(n) {
500 self.add_empty_node(n);
504 fn set_face(&mut self, ((x, y, z), o): Face, v: Option<FaceColor>) {
505 match self.faces[x][y][z] {
507 if f[Space::ori_idx(o)] != v {
508 println!("face change");
509 self.change = Change::Space;
511 f[Space::ori_idx(o)] = v;
513 None => panic!("there is no node here"),
517 fn face_adj_available_faces(&self, f: Face) -> Vec<Face> {
518 let mut faces = Vec::new();
519 for e in self.face_edges(f) {
520 for adj_f in self.adj_available_faces(e) {
529 fn suround_with_nodes(&mut self, (n, o): Face) {
530 assert!(self.is_node(n));
531 for (nf, _) in self.face_adj_available_faces((n, o)) {
532 self.add_empty_node_if_none(nf);
536 pub fn add_face(&mut self, f: Face) {
537 self.suround_with_nodes(f);
538 self.set_face(f, Some((1.0, 1.0, 1.0)));
541 pub fn remove_face(&mut self, f: Face) {
542 assert!(self.is_face(f));
543 //panic!("not yet implemented");
544 self.set_face(f, None);
547 pub fn set_current_face_if_none(&mut self) {
549 Pos::F(f) => if !self.is_face(f) { self.add_face(f) },
554 //fn is_edge(&self, (c, a): Edge) -> bool {
555 // assert!(self.is_node(c));
556 // self.is_adj_existing_faces((c, a))
559 //pub fn row_size_after_current(&self, a: Axis) -> usize {
560 // let (xcur, ycur, zcur) = self.current_node_coord();
564 // let xidx = Space::axis_idx(Axis::X);
565 // for x in xcur..self.size[xidx].len() {
566 // res += self.size[xidx][x];
570 // let yidx = Space::axis_idx(Axis::Y);
571 // for y in ycur..self.size[yidx].len() {
572 // res += self.size[yidx][y];
576 // let zidx = Space::axis_idx(Axis::Z);
577 // for z in zcur..self.size[zidx].len() {
578 // res += self.size[zidx][z];
585 //pub fn get_current_face_color_if_any(&self) -> Option<FaceColor> {
586 // match self.current {
587 // Pos::E(_) => None,
588 // Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
589 // Some(ref f) => f[Space::ori_idx(o)],
595 //fn is_adj_existing_faces(&self, e: Edge) -> bool {
596 // for f in Space::adj_faces(e).iter() {
597 // if self.is_face(*f) {
604 //fn remove_node(&mut self, (x, y, z): Coord) {
605 // assert!(self.is_node((x, y, z)));
606 // panic!("nothing here");
609 //fn remove_node_if_any(&mut self, n: Coord) {
610 // if self.is_node(n) {
611 // self.remove_node(n);
615 //fn face_adj_existing_faces(&self, f: Face) -> Vec<Face> {
616 // let mut faces = Vec::new();
617 // for e in self.face_edges(f) {
618 // for adj_f in self.adj_existing_faces(e) {
620 // faces.push(adj_f);
628 impl Clone for Space {
629 fn clone(&self) -> Space {
633 current: self.current,
653 fn new() -> History {
661 fn add(&mut self, s: Save) {
662 if self.saves.len() > self.id {
663 println!("clear next saves");
664 while self.saves.len() > self.id {
672 pub fn has_prev(&self) -> bool {
676 pub fn has_next(&self) -> bool {
677 self.saves.len() > self.id
680 fn prev(&mut self) -> Save {
681 assert!(self.has_prev());
684 self.saves[self.id-1].clone()
687 fn next(&mut self) -> Save {
688 assert!(self.has_next());
691 self.saves[self.id-1].clone()
694 fn current(&self) -> Option<&Save> {
698 Some(&self.saves[self.id-1])
702 fn replace_current(&mut self, s: Save) {
703 assert!(self.id != 0);
704 self.saves[self.id-1] = s;
710 pub history: History,
714 pub fn new() -> Data {
715 Data { space: Space::new(), history: History::new() }
718 fn save_to_add(&self) -> Option<Save> {
719 match self.space.change {
721 let mut space = self.space.clone();
722 space.change = Change::None;
723 Some(Save::Space(space))
725 Change::Current => Some(Save::Current(self.space.current)),
726 Change::Size(e, s) => Some(Save::Size(e, s)),
727 Change::None => None,
731 pub fn save_if_changed(&mut self) {
732 match self.save_to_add() {
733 Some(Save::Size(e, s)) =>
734 match self.history.current() {
735 Some(&Save::Size(e, _)) =>
736 self.history.replace_current(Save::Size(e, s)),
737 _ => self.history.add(Save::Size(e, s)),
739 Some(s) => self.history.add(s),
742 self.space.change = Change::None;
745 pub fn load_prev(&mut self) {
746 println!("load prev");
747 match self.history.prev() {
748 Save::Current(c) => self.space.current = c,
749 Save::Space(s) => self.space = s,
750 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
754 pub fn load_next(&mut self) {
755 println!("load next");
756 match self.history.next() {
757 Save::Current(c) => self.space.current = c,
758 Save::Space(s) => self.space = s,
759 Save::Size(e, s) => self.space.edge_size_no_change(e, s),
763 pub fn load_prev_if_any(&mut self) {
764 if self.history.has_prev() {
769 pub fn load_next_if_any(&mut self) {
770 if self.history.has_next() {