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); } }
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; } }