Beispiel #1
0
 public BothTri(BothTri bothTri, int tabId) : this(bothTri.Space, bothTri.SpaceToPaper)
 {
     TabId = tabId;
 }
Beispiel #2
0
 public BothTri(BothTri bothTri, int tabId, Vec3[] common) : this(bothTri, tabId)
 {
     CommonSpace = common;
     CommonPaper = common.Select(p => SpaceToPaper.Apply(p)).ToArray();
 }
Beispiel #3
0
        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);
        }