diff --git a/bigstuff.cpp b/bigstuff.cpp index f059a5c3..ef324d9a 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -253,6 +253,8 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special if(hybri) alt->fieldval = hybrid::get_where(centerover).second; alt->c7 = NULL; alt->alt = alt; + if(reg3::geometry_has_tree_structure()) + reg3::link_structures(h, alt); h->alt = alt; alt->cdata = (cdata*) h; currentmap->link_alt(bf); diff --git a/cell.cpp b/cell.cpp index a76ff566..99e50614 100644 --- a/cell.cpp +++ b/cell.cpp @@ -145,7 +145,11 @@ EX cell *newCell(int type, heptagon *master) { EX hrmap *currentmap; EX vector allmaps; -EX hrmap *newAltMap(heptagon *o) { return new hrmap_hyperbolic(o); } +EX hrmap *newAltMap(heptagon *o) { + if(reg3::geometry_has_tree_structure()) + return reg3::new_alt_map(o); + return new hrmap_hyperbolic(o); + } // --- hyperbolic geometry --- EX heptagon* hyperbolic_origin() { diff --git a/honeycomb-435.dat b/honeycomb-435.dat new file mode 100644 index 00000000..77e59b97 Binary files /dev/null and b/honeycomb-435.dat differ diff --git a/honeycomb-534.dat b/honeycomb-534.dat new file mode 100644 index 00000000..644c2c00 Binary files /dev/null and b/honeycomb-534.dat differ diff --git a/honeycomb-535.dat b/honeycomb-535.dat new file mode 100644 index 00000000..8f187c48 Binary files /dev/null and b/honeycomb-535.dat differ diff --git a/pattern2.cpp b/pattern2.cpp index efdae879..3627f78c 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -2544,6 +2544,12 @@ EX namespace linepatterns { ALLCELLS( if(is_master(c)) { int dir = bt::in() ? bt::updir() : 0; + if(WDIM == 3 && standard_tiling()) { + for(int i=0; imove(i) && c->move(i)->master->distance < c->master->distance) { + dir = i; + break; + } + } cell *c2 = c->master->move(dir)->c7; if(gmatrix.count(c2)) { if(S3 >= OINF) diff --git a/reg3.cpp b/reg3.cpp index 8265d35f..32037059 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -875,12 +875,228 @@ EX namespace reg3 { return vertices_only; } }; + + struct hrmap_reg3_rule : hrmap { + + heptagon *origin; + reg3::hrmap_quotient3 *quotient_map; + + fieldpattern::fpattern fp; + + int root; + string other; + vector children; + + vector otherpos; + + void load_ruleset(string fname) { + FILE *f = fopen(fname.c_str(), "rb"); + string buf; + buf.resize(1000000); + int qty = fread(&buf[0], 1, 1000000, f); + buf.resize(qty); + + shstream ins(decompress_string(buf)); + hread_fpattern(ins, fp); + + hread(ins, root); + hread(ins, children); + hread(ins, other); + fclose(f); + } + + hrmap_reg3_rule() : fp(0) { + + if(S7 == 6) load_ruleset("honeycomb-435.dat"); + else if(ginf[geometry].vertex == 5) load_ruleset("honeycomb-535.dat"); + else load_ruleset("honeycomb-534.dat"); + + reg3::generate(); + origin = tailored_alloc (S7); + heptagon& h = *origin; + h.s = hsOrigin; + h.cdata = NULL; + h.alt = NULL; + h.distance = 0; + h.zebraval = 0; + h.fieldval = 0; + h.fiftyval = root; + h.c7 = NULL; + h.c7 = newCell(S7, origin); + + int opos = 0; + for(int c: children) { + if(c >= 0) + otherpos.push_back(-1); + else { + otherpos.push_back(opos); + while(other[opos] != ',') opos++; + opos++; + } + } + + quotient_map = nullptr; + + if(geometry == gSpace535) + quotient_map = new seifert_weber::hrmap_seifert_cover(); + else + quotient_map = new hrmap_field3(&fp); + h.zebraval = quotient_map->allh[0]->zebraval; + } + + heptagon *getOrigin() override { + return origin; + } + + #define DEB 0 + + heptagon *counterpart(heptagon *h) { + return quotient_map->allh[h->fieldval]; + } + + heptagon *create_step(heptagon *parent, int d) override { + int id = parent->fiftyval; + + auto cp = counterpart(parent); + int d2 = cp->c.spin(d); + int fv = cp->c.move(d)->fieldval; + + // indenter ind(2); + + heptagon *res = nullptr; + + int id1 = children[S7*id+d]; + int pos = otherpos[S7*id+d]; + // println(hlog, "id=", id, " d=", d, " d2=", d2, " id1=", id1, " pos=", pos); + if(id1 != -1) { + res = tailored_alloc (S7); + if(parent->c7) + res->c7 = newCell(S7, res); + else + res->c7 = nullptr; + res->alt = nullptr; + res->cdata = nullptr; + res->zebraval = quotient_map->allh[fv]->zebraval; + res->fieldval = fv; + res->distance = parent->distance + 1; + res->fiftyval = id1; + // res->c.connect(d2, parent, d, false); + } + + else if(other[pos] == ('A' + d) && other[pos+1] == ',') { + println(hlog, "parent link of ", id); + res = tailored_alloc (S7); + res->c7 = nullptr; + res->alt = parent->alt; + res->cdata = nullptr; + res->fieldval = fv; + res->distance = parent->distance - 1; + vector possible; + for(int i=0; ififtyval = id1; + } + + else { + heptagon *at = parent; + while(other[pos] != ',') { + int dir = (other[pos++] & 31) - 1; + // println(hlog, "from ", at, " go dir ", dir); + at = at->cmove(dir); + } + res = at; + } + + if(!res) throw "res missing"; + + if(res->move(d2)) println(hlog, "res conflict"); + + res->c.connect(d2, parent, d, false); + return res; + } + + ~hrmap_reg3_rule() { + if(quotient_map) delete quotient_map; + clearfrom(origin); + } + + void draw() override { + sphereflip = Id; + + // for(int i=0; imaster, cview()); + + while(!dq::drawqueue.empty()) { + auto& p = dq::drawqueue.front(); + heptagon *h = get<0>(p); + transmatrix V = get<1>(p); + dynamicval b(band_shift, get<2>(p)); + bandfixer bf(V); + dq::drawqueue.pop(); + + + cell *c = h->c7; + if(!do_draw(c, V)) continue; + drawcell(c, V); + if(in_wallopt() && isWall3(c) && isize(dq::drawqueue) > 1000) continue; + + for(int i=0; imove(i)) { + dq::enqueue(h->move(i), V * adj(h, i)); + } + } + } + + transmatrix adj(heptagon *h, int d) override { + return quotient_map->adj(h, d); + } + + transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override { + if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7)) + return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7]; + println(hlog, "unknown"); + return Id; + } + + vector get_vertices(cell* c) override { + return reg3::vertices_only; + } + }; + + struct hrmap_reg3_rule_alt : hrmap { + + heptagon *origin; + + hrmap_reg3_rule_alt(heptagon *o) { + origin = o; + } + + }; + +EX hrmap *new_alt_map(heptagon *o) { + return new hrmap_reg3_rule_alt(o); + } + +EX void link_structures(heptagon *h, heptagon *alt) { + alt->fieldval = h->fieldval; + alt->fiftyval = h->fiftyval; + } + +EX bool geometry_has_tree_structure() { + return among(geometry, gSpace534, gSpace435, gSpace535); + } EX hrmap* new_map() { if(geometry == gSeifertCover) return new seifert_weber::hrmap_seifert_cover; if(geometry == gSeifertWeber) return new seifert_weber::hrmap_singlecell(108*degree); if(geometry == gHomologySphere) return new seifert_weber::hrmap_singlecell(36*degree); if(quotient && !sphere) return new hrmap_field3(&currfp); + if(among(geometry, gSpace534, gSpace435, gSpace535)) return new hrmap_reg3_rule; return new hrmap_reg3; } @@ -932,10 +1148,15 @@ EX bool pseudohept(cell *c) { if(geometry == gCrystal344 || geometry == gCrystal534 || geometry == gSeifertCover) return false; if(quotient) return false; /* added */ - if(hyperbolic) { + auto mr = dynamic_cast (currentmap); + if(mr) { + return c->master->fieldval == 0; + } + if(m && hyperbolic) { heptagon *h = m->reg_gmatrix[c->master].first; return (h->zebraval == 1) && (h->distance & 1); } + return false; }