public BothTri(BothTri bothTri, int tabId) : this(bothTri.Space, bothTri.SpaceToPaper) { TabId = tabId; }
public BothTri(BothTri bothTri, int tabId, Vec3[] common) : this(bothTri, tabId) { CommonSpace = common; CommonPaper = common.Select(p => SpaceToPaper.Apply(p)).ToArray(); }
private static IEnumerable <BothTri> FlattenWorker( Mesh mesh, SpanningTree spanTree, Tri3 curr, BothTri prev, HashSet <int> visitedNodes, int depth) { // Console.WriteLine("".PadLeft(depth, '.') + curr.Index); if (visitedNodes.Contains(curr.Index)) { return(new BothTri[0]); } visitedNodes.Add(curr.Index); var node = curr; Tri3 nodePrev = null; if (prev != null) { // Need to treat the common edge special. var ab = curr.CommonEdge(prev.Space); var abi = ab.Select(p => p.Index).ToArray(); var c = curr.Vertices.Where(p => !abi.Contains(p.Index)).Single(); var origOrder = curr.Vertices.Select(p => p.Index).ToArray(); var newOrder = new int[] { ab[0].Index, ab[1].Index, c.Index }; var curr2 = new Tri3(ab[0], ab[1], c, curr.Index); curr = new Tri3(ab[0], ab[1], c, curr.Index); node = prev.SpaceToPaper.Apply(curr); var c2 = prev.Space.Vertices.Where(p => !abi.Contains(p.Index)).Single(); nodePrev = new Tri3(ab[0], ab[1], c2); nodePrev = prev.SpaceToPaper.Apply(nodePrev); } var tri1 = node.Translate(node.A.Neg()); var BYtoX = tri1.B.GetXYRot(); var tri2 = tri1.Apply(BYtoX); var BZtoX = tri2.B.GetXZRot(); var tri3 = tri2.Apply(BZtoX); var CZtoY = tri3.C.GetYZRot(); var tri4 = tri3.Apply(CZtoY); nodePrev = nodePrev?.Translate(node.A.Neg()).Apply(BYtoX).Apply(BZtoX); // Need to check if rotation put tri4 over prev.Paper. This is easy because the common axis is along x, and z=0. if (prev != null) { // Need to determine which if (tri4.C.Y > 0 && nodePrev.C.Y > 0) { // overlap. Just need to do another rotation around xhat. CZtoY = Mat3.RotateYZ(Math.PI).Mult(CZtoY); } } Mat3 spaceToPaper = CZtoY.Mult(BZtoX.Mult(BYtoX)); if (prev != null) { // Need to restore angle of the common edge. spaceToPaper = BYtoX.Inv().Mult(BZtoX.Inv().Mult(spaceToPaper)); } Transform t; if (prev == null) { t = Transform.ContructRT(node.A.Neg(), spaceToPaper); } else { t = Transform.ContructTRT(node.A.Neg(), spaceToPaper); } if (prev != null) { // Apply atop previous transform t = t.Compose(prev.SpaceToPaper); } var test1 = t.Apply(curr); if (Math.Abs(test1.C.Z) > 1e-8) { throw new InvalidOperationException(); } var test4 = curr; BothTri bt = new BothTri(curr, t); var test0 = bt.Paper; var test2 = bt.SpaceToPaper.Apply(curr); var test3 = bt.PaperToSpace(bt.Paper); var test5 = bt.Space; if (test0.Dist(test1) > 1e-5) { throw new InvalidOperationException(); } if (test0.Dist(test2) > 1e-5) { throw new InvalidOperationException(); } if (test3.Dist(test4) > 1e-5) { throw new InvalidOperationException(); } if (test3.Dist(test5) > 1e-5) { throw new InvalidOperationException(); } var ret = new List <BothTri>() { bt }; foreach (Tri3 child in spanTree.GetConnectedNodes(curr)) { var cbt = FlattenWorker(mesh, spanTree, child, bt, visitedNodes, depth + 1); ret.AddRange(cbt); } return(ret); }