public void Add(Vector3 v, float e, float d) { if (pointsLists.Count == 0) pointsLists.AddLast(new LinkedList<GCodePoint>()); GCodePoint pt = new GCodePoint(); pt.p = v; pt.e = e; pt.dist = d; pointsCount++; pointsLists.Last.Value.AddLast(pt); drawMethod = -1; // invalidate old }
public void Add(Vector3 v, float e, float d) { if (pointsLists.Count == 0) { pointsLists.AddLast(new LinkedList <GCodePoint>()); } GCodePoint pt = new GCodePoint(); pt.p = v; pt.e = e; pt.dist = d; pointsCount++; pointsLists.Last.Value.AddLast(pt); drawMethod = -1; // invalidate old }
public void UpdateVBO(bool buffer) { if (pointsCount < 2) { return; } if (hasBuf) { GL.DeleteBuffers(3, buf); } hasBuf = false; int method = Main.threeDSettings.filamentVisualization; float h = Main.threeDSettings.layerHeight; float wfac = Main.threeDSettings.widthOverHeight; float w = h * wfac; bool fixedH = Main.threeDSettings.useLayerHeight; float dfac = (float)(Math.PI * Main.threeDSettings.filamentDiameter * Main.threeDSettings.filamentDiameter * 0.25 / wfac); int nv = 8 * (method - 1), i; if (method == 1) { nv = 4; } if (method == 0) { nv = 1; } int n = nv * (method == 0 ? 1 : 2) * (pointsCount - pointsLists.Count); //if (method != 0) positions = new float[n * 3]; else positions = new float[3 * pointsCount]; //if (method != 0) normals = new float[n * 3]; else normals = null; if (method != 0) { positions = new float[pointsCount * nv * 3]; } else { positions = new float[3 * pointsCount]; } if (method != 0) { normals = new float[pointsCount * nv * 3]; } else { normals = null; } if (method != 0) { elements = new int[(pointsCount - pointsLists.Count) * nv * 4 + pointsLists.Count * (nv - 2) * 4]; } else { elements = new int[n * 2]; } int pos = 0; int npos = 0; int vpos = 0; if (method > 0) { float alpha, dalpha = (float)Math.PI * 2f / nv; float[] dir = new float[3]; float[] dirs = new float[3]; float[] diru = new float[3]; float[] norm = new float[3]; float[] lastdir = new float[3]; float[] actdir = new float[3]; float laste = 0; float dh = 0.5f * h; float dw = 0.5f * w; bool first = true; Vector3 last = new Vector3(); w *= 0.5f; int nv2 = 2 * nv; foreach (LinkedList <GCodePoint> points in pointsLists) { if (points.Count < 2) { continue; } first = true; LinkedListNode <GCodePoint> ptNode = points.First; while (ptNode != null) { GCodePoint pt = ptNode.Value; GCodePoint ptn = null; if (ptNode.Next != null) { ptn = ptNode.Next.Value; } ptNode = ptNode.Next; Vector3 v = pt.p; if (first) { last = v; laste = pt.e; lastdir[0] = actdir[0] = ptn.p.X - v.X; lastdir[1] = actdir[1] = ptn.p.Y - v.Y; lastdir[2] = actdir[2] = ptn.p.Z - v.Z; GCodeVisual.normalize(ref lastdir); // first = false; // continue; } else { bool isLast = pt == points.Last.Value; if (isLast) { actdir[0] = v.X - last.X; actdir[1] = v.Y - last.Y; actdir[2] = v.Z - last.Z; } else { actdir[0] = ptn.p.X - v.X; actdir[1] = ptn.p.Y - v.Y; actdir[2] = ptn.p.Z - v.Z; } } if (!fixedH) { float dist = (float)Math.Sqrt(actdir[0] * actdir[0] + actdir[1] * actdir[1] + actdir[2] * actdir[2]); if (dist > 0) { h = (float)Math.Sqrt((pt.e - laste) * dfac / dist); w = h * wfac; dh = 0.5f * h; dw = 0.5f * w; } } GCodeVisual.normalize(ref actdir); dir[0] = actdir[0] + lastdir[0]; dir[1] = actdir[1] + lastdir[1]; dir[2] = actdir[2] + lastdir[2]; GCodeVisual.normalize(ref dir); float zoomw = dir[0] * lastdir[0] + dir[1] * lastdir[1] + dir[2] * lastdir[2]; lastdir[0] = actdir[0]; lastdir[1] = actdir[1]; lastdir[2] = actdir[2]; dirs[0] = -dir[1]; dirs[1] = dir[0]; dirs[2] = dir[2]; diru[0] = diru[1] = 0; diru[2] = 1; alpha = 0; float c, s; int b = vpos / 3 - nv; for (i = 0; i < nv; i++) { c = (float)Math.Cos(alpha) * dh; s = (float)Math.Sin(alpha) * dw / zoomw; norm[0] = (float)(s * dirs[0] + c * diru[0]); norm[1] = (float)(s * dirs[1] + c * diru[1]); norm[2] = (float)(s * dirs[2] + c * diru[2]); GCodeVisual.normalize(ref norm); if (!first) { elements[pos++] = b + (i + 1) % nv; //2 elements[pos++] = b + i; //1 elements[pos++] = b + i + nv; //4 elements[pos++] = b + (i + 1) % nv + nv; //3 } normals[npos++] = norm[0]; normals[npos++] = norm[1]; normals[npos++] = norm[2]; positions[vpos++] = v.X + s * dirs[0] + c * diru[0]; positions[vpos++] = v.Y + s * dirs[1] + c * diru[1]; positions[vpos++] = v.Z - dh + s * dirs[2] + c * diru[2]; alpha += dalpha; } if (first || ptNode == null) // Draw cap { b = vpos / 3 - nv; int nn = (nv - 2) / 2; for (i = 0; i < nn; i++) { if (first) { elements[pos++] = b + i; elements[pos++] = b + i + 1; elements[pos++] = b + nv - i - 2; elements[pos++] = b + nv - i - 1; } else { elements[pos++] = b + nv - i - 1; elements[pos++] = b + nv - i - 2; elements[pos++] = b + i + 1; elements[pos++] = b + i; } } } last = v; laste = pt.e; first = false; } } if (buffer) { GL.GenBuffers(3, buf); GL.BindBuffer(BufferTarget.ArrayBuffer, buf[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(positions.Length * sizeof(float)), positions, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, buf[1]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, buf[2]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(elements.Length * sizeof(int)), elements, BufferUsageHint.StaticDraw); // GL.BindBuffer(BufferTarget.ArrayBuffer, 0); hasBuf = true; } } else { // Draw edges bool first = true; foreach (LinkedList <GCodePoint> points in pointsLists) { first = true; foreach (GCodePoint pt in points) { Vector3 v = pt.p; positions[vpos++] = v.X; positions[vpos++] = v.Y; positions[vpos++] = v.Z; if (!first) { elements[pos] = pos / 2; elements[pos + 1] = pos / 2 + 1; pos += 2; } first = false; } } if (buffer) { GL.GenBuffers(3, buf); GL.BindBuffer(BufferTarget.ArrayBuffer, buf[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(positions.Length * sizeof(float)), positions, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, buf[2]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(elements.Length * sizeof(int)), elements, BufferUsageHint.StaticDraw); hasBuf = true; } } drawMethod = method; }