Exemple #1
0
        internal PAxis(PAxis src, double [] tw)
        {
            Base   = src.Base;
            Dir    = PGeom.ApplyTwist(tw, src.Dir);
            Matrix = PGeom.ApplyTwist(tw, src.Matrix);
            int ntw = src.Twists.Length;

            Twists = new double[ntw][];
            for (int i = 0; i < ntw; i++)
            {
                Twists[i] = PGeom.ApplyTwist(tw, src.Twists[i]);
            }
        }
Exemple #2
0
        internal int BaseSticker(int st, int ax)
        {
            int   rax = Math.Abs(ax) - 1;
            PAxis p   = Axes[rax];
            int   lv  = ax > 0 ? 0 : p.Layers.Length - 1;

            int[] L = p.Layers[lv];
            for (int i = 0; i < L.Length; i++)
            {
                if (L[i] == st)
                {
                    return(i);
                }
            }
            throw new Exception("Can't find sticker in Layer");
        }
Exemple #3
0
        void MakeMacroStep(long code, double[,] matr, bool qrev)
        {
            int ax, tw, an, ms;

            UnpackCode(code, out ax, out tw, out an, out ms);
            PAxis A   = Str.Axes[ax];
            int   ax1 = AxisMap[ax];

            if (ax1 == 0)
            {
                AxisMap[ax] = ax1 = Str.FindAxis(A.Dir, matr);
            }
            if (ax1 < 0)
            {
                ms  = A.Base.ReverseMask(ms);
                ax1 = -ax1;
            }
            ax1--;
            PAxis A1 = Str.Axes[ax1];

            if (TwistMap[ax] == null)
            {
                TwistMap[ax] = new int[A1.Twists.Length];
            }
            int tw1 = TwistMap[ax][tw];

            if (tw1 == 0)
            {
                bool qrev1;
                tw1 = A1.FindTwist(A.Twists[tw], matr, out qrev1);
                tw1 = qrev1 ? -1 - tw1 : 1 + tw1;
                TwistMap[ax][tw] = tw1;
            }
            if (tw1 < 0)
            {
                qrev = !qrev;
                tw1  = -tw1;
            }
            tw1--;
            if (qrev)
            {
                an = -an;
            }
            TwistNormMask(ax1, tw1, an, ms);
        }
Exemple #4
0
        private void ExpandAxes()
        {
            int q = BaseAxes.Length;

            PAxis[] CAxes = new PAxis[MaxNAxes];
            for (int i = 0; i < q; i++)
            {
                PBaseAxis ax = BaseAxes[i];
                ax.Id = i;
                ax.ExpandPrimaryTwists();
                CAxes[i] = new PAxis(ax); // matrix=id
            }
            for (int p = 0; p < q; p++)
            {
                double[] R = CAxes[p].Dir;
                foreach (double [] G in Group)
                {
                    double[] v = PGeom.ApplyTwist(G, R);
                    int      j;
                    bool     qr;
                    for (j = 0; j < q; j++)
                    {
                        if (PGeom.AxisEqual(v, CAxes[j].Dir, out qr))
                        {
                            break;
                        }
                    }
                    if (j == q)
                    {
                        if (q == MaxNAxes)
                        {
                            throw new Exception("Too many axes");
                        }
                        CAxes[q] = new PAxis(CAxes[p], G);
                        q++;
                    }
                }
            }
            Axes = new PAxis[q];
            for (int i = 0; i < q; i++)
            {
                Axes[i]    = CAxes[i];
                Axes[i].Id = i;
            }
        }
Exemple #5
0
        internal void SetTwist(int axis, int mask, Func <int, bool> F)    // for animation
        {
            PAxis A = Str.Axes[axis];

            mask = A.Base.Remask(mask);  // insert or clear zero layer if necessary
            int k = 0;

            while (mask != 0)
            {
                if ((mask & 1) != 0)
                {
                    foreach (int s in A.Layers[k])
                    {
                        F(s);
                    }
                }
                mask >>= 1; k++;
            }
        }
Exemple #6
0
        private unsafe void DoTwist(int axis, int twist, int angle, int mask)
        {
            Buffer.BlockCopy(Field, 0, Fld2, 0, NStk * sizeof(short));
            PAxis A = Str.Axes[axis];

            angle = A.Base.Twists[twist].NormAngle(angle);  // symmetric class of remainders
            if (angle == 0)
            {
                return;
            }
            int a = Math.Abs(angle);
            int k = 0;

            while (mask != 0)
            {
                if ((mask & 1) != 0)
                {
                    int[] stks = A.Layers[k];
                    int[] map  = angle < 0 ? A.Base.Twists[twist].InvMap[k] : A.Base.Twists[twist].Map[k];
                    int   lm   = map.Length;
                    if (a == 1)
                    {
                        for (int i = 0; i < lm; i++)
                        {
                            Field[stks[map[i]]] = Fld2[stks[i]];
                        }
                    }
                    else
                    {
                        for (int i = 0; i < lm; i++)
                        {
                            int x = i;
                            for (int j = 0; j < a; j++)
                            {
                                x = map[x];
                            }
                            Field[stks[x]] = Fld2[stks[i]];
                        }
                    }
                }
                mask >>= 1; k++;
            }
        }
Exemple #7
0
        internal int CheckTwist(int ax, int[] stkseq, int lstkseq, short[] fld, out int tw)
        {
            for (int i = 0; i < NStickers; i++)
            {
                fld[i] &= 0x7fff;
            }
            int rax = Math.Abs(ax) - 1;

            tw = 0;

            PAxis p  = Axes[rax];
            int   lv = ax > 0 ? 0 : p.Base.NLayers - 1;

            int[] L   = p.Layers[lv], LB = p.Base.Layers[lv];
            int   ntw = p.Twists.Length;

            int[] tws  = new int[ntw * 2];
            int   ntws = 0;

            for (int i = 0; i < ntw; i++)
            {
                int[] LT = p.Base.Twists[i].Map[lv];
                bool  q = true, q1 = true;
                for (int a = 0; a < lstkseq - 1; a++)
                {
                    int h = stkseq[a], h1 = stkseq[a + 1];
                    if (h < 0 || h1 < 0)
                    {
                        continue;
                    }
                    if (LT[h] != h1)
                    {
                        q = false;
                    }
                    if (LT[h1] != h)
                    {
                        q1 = false;
                    }
                    if (!q && !q1)
                    {
                        break;
                    }
                }
                if (q)
                {
                    tws[ntws++] = i + 1;
                }
                if (q1)
                {
                    tws[ntws++] = -i - 1;
                }
            }
            if (ntws == 0)
            {
                throw new Exception("No twists for stkseq");
            }
            if (ntws == 1)
            {
                tw = ax < 0 ? -tws[0] : tws[0]; return(2); // finita
            }
            if (lstkseq != 0)
            {
                int a = stkseq[lstkseq - 1];
                if (a >= 0)
                {
                    int nnext = 0;
                    int _b    = 0;
                    for (int b = 0; b < ntws; b++)
                    {
                        int t  = tws[b];
                        int b1 = t > 0 ? p.Base.Twists[t - 1].Map[lv][a] : p.Base.Twists[-t - 1].InvMap[lv][a];
                        b1 = L[b1];
                        if ((fld[b1] & 0x8000) == 0)
                        {
                            nnext++; fld[b1] |= unchecked ((short)0x8000);
                            _b = b1;
                        }
                    }
                    if (nnext > 1)
                    {
                        return(0);        // continue;
                    }
                    fld[_b] &= 0x7fff;
                }
            }
            int nq = 0;

            for (int a = 0; a < LB.Length; a++)
            {
                int  _b = -1;
                bool qc = false;
                for (int b = 0; b < ntws; b++)
                {
                    int t  = tws[b];
                    int b1 = t > 0 ? p.Base.Twists[t - 1].Map[lv][a] : p.Base.Twists[-t - 1].InvMap[lv][a];
                    if (_b < 0)
                    {
                        _b = b1;
                    }
                    else if (_b != b1)
                    {
                        qc = true; break;
                    }
                }
                if (qc)
                {
                    fld[L[a]] |= unchecked ((short)0x8000);
                    nq++;
                }
            }
            if (nq != 0)
            {
                return(1);
            }
            tw = ax < 0 ? -tws[0] : tws[0]; return(2);
        }
Exemple #8
0
        private void CutFaces()
        {
            double RMax = 0;

            foreach (PBaseFace F in BaseFaces)
            {
                RMax = Math.Max(RMax, PGeom.VLength(F.Pole));
            }
            int minrank = int.MaxValue;

            foreach (PBaseFace F in BaseFaces)
            {
                CutNode  face = CutNode.GenCube(Dim, RMax * Dim);
                double[] hpln = CutNetwork.GetPlane(F.Pole, 1);
                face.Split(1, hpln, false);
                face = face.ZeroNode;
                int opgen = 1;
                foreach (PFace FF in Faces)
                {
                    if (F.Id != FF.Id)
                    {
                        hpln = CutNetwork.GetPlane(FF.Pole, 1);
                        face.Split(++opgen, hpln, true);
                        if (face.Status != CutNode.STAT_PLUS)
                        {
                            throw new Exception("Empty face: Id=" + F.Id);
                        }
                    }
                }

                int        nff   = face.Children.Length;
                double[][] ffpol = new double[nff][];
                for (int i = 0; i < nff; i++)
                {
                    ffpol[i] = face.Children[i].Pole;
                }
                F.FPoles = ffpol;

                LMesh m = new LMesh(Dim, true);
                face.FillLMesh(++opgen, m);
                m.CloseCtr();
                F.FaceMesh      = new PMesh(m);
                F.FaceMesh.FCtr = F.Pole;

                double[]   verts  = m.pts;
                int        nverts = m.npts;
                CutNetwork CN     = new CutNetwork(face, Dim, opgen);
                double[][] fctrs  = null;
                if (QSimplified)
                {
                    fctrs = CN.GetCtrs();
                }
                F.AxisLayers = new int[Axes.Length];
                for (int u = 0; u < Axes.Length; u++)
                {
                    PAxis    Ax = Axes[u];
                    double[] D = Ax.Dir;
                    double   lD = PGeom.Dist2(D, new double[Dim]);
                    double   smin = double.MaxValue, smax = double.MinValue;
                    for (int i = 0; i < nverts; i++)
                    {
                        double v = 0;
                        for (int j = 0; j < Dim; j++)
                        {
                            v += D[j] * verts[i * Dim + j];
                        }
                        if (v < smin)
                        {
                            smin = v;
                        }
                        if (v > smax)
                        {
                            smax = v;
                        }
                    }
                    smin /= lD; smax /= lD;
                    bool cs = false, cc = false;
                    int  k = Ax.Base.NLayers - 1;
                    for (int i = 0; i < Ax.Base.Cut.Length; i++)
                    {
                        double p = Ax.Base.Cut[i];
                        if (p >= smax - 0.0001)
                        {
                            continue;
                        }
                        if (!cs)
                        {
                            k = i; cs = true;
                        }
                        if (p <= smin + 0.0001)
                        {
                            break;
                        }
                        hpln = CutNetwork.GetPlane(Ax.Dir, p);
                        CN.Split(hpln, false);
                        cc = true;
                    }
                    if (cc)
                    {
                        k = -1;
                    }
                    F.AxisLayers[u] = k;
                }
                F.SetStickers(m, CN, Axes, fctrs);
                minrank = Math.Min(minrank, F.MinRank());
            }
            foreach (PBaseFace F in BaseFaces)
            {
                F.SubRank(minrank);
            }
        }
Exemple #9
0
        internal void SetStickers(LMesh M, CutNetwork CN, PAxis[] Axes, double[][] fctrs)
        {
            int dim = Pole.Length;

            NCutAxes = 0;
            int nax = Axes.Length;

            for (int i = 0; i < nax; i++)
            {
                if (AxisLayers[i] < 0)
                {
                    NCutAxes++;
                }
            }
            CutAxes = new int[NCutAxes];
            int d   = 0;
            int rnk = 0;

            for (int u = 0; u < nax; u++)
            {
                if (AxisLayers[u] < 0)
                {
                    CutAxes[d++] = u;
                }
                else
                {
                    rnk += Axes[u].Base.GetRank(AxisLayers[u]);
                }
            }

            NStickers   = CN.Nodes.Length;
            StickerMask = new byte[NStickers, NCutAxes];
            StickerMesh = new PMesh[NStickers];
            int nstk = 0;

            for (int i = 0; i < NStickers; i++)
            {
                PMesh xx = CN.GetPMesh(i);
                if (fctrs != null)
                {
                    bool qg = false;
                    foreach (double[] p in fctrs)
                    {
                        if (PGeom.VertEqual(p, xx.Ctr))
                        {
                            qg = true;
                            break;
                        }
                    }
                    if (!qg)
                    {
                        continue;
                    }
                }

                xx.FCtr = Pole;
                double[] ctr  = xx.GetMCtr();
                int      rnk1 = rnk;
                for (int j = 0; j < NCutAxes; j++)
                {
                    PAxis    ax = Axes[CutAxes[j]];
                    double[] h  = ax.Dir;
                    double   lh = PGeom.DotProd(h, h);
                    double   s  = 0;
                    for (int k = 0; k < dim; k++)
                    {
                        s += ctr[k] * h[k];
                    }
                    s /= lh;
                    int lv = ax.Base.NLayers - 1;
                    for (int g = 0; g < lv; g++)
                    {
                        if (s > ax.Base.Cut[g])
                        {
                            lv = g; break;
                        }
                    }
                    rnk1 += ax.Base.GetRank(lv);
                    StickerMask[nstk, j] = (byte)lv;
                }
                xx.Rank             = rnk1;
                StickerMesh[nstk++] = xx;
            }
            if (nstk != NStickers)
            {
                PMesh[] stkm = new PMesh[nstk];
                byte[,] stkmsk = new byte[nstk, NCutAxes];
                for (int i = 0; i < nstk; i++)
                {
                    stkm[i] = StickerMesh[i];
                    for (int j = 0; j < NCutAxes; j++)
                    {
                        stkmsk[i, j] = StickerMask[i, j];
                    }
                }
                StickerMask = stkmsk;
                StickerMesh = stkm;
                NStickers   = nstk;
            }
        }