public void drawSegment(GCodePath path) { if (Main.threeDSettings.drawMethod == 2) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.AmbientAndDiffuse, defaultColor); GL.EnableClientState(ArrayCap.VertexArray); if (path.drawMethod != method || recompute) { path.UpdateVBO(true); } else if (path.hasBuf == false && path.elements != null) path.RefillVBO(); if (path.elements == null) return; GL.BindBuffer(BufferTarget.ArrayBuffer, path.buf[0]); GL.VertexPointer(3, VertexPointerType.Float, 0, 0); float[] cp; if (liveView && path.lastDist > minHotDist) { GL.EnableClientState(ArrayCap.ColorArray); cp = new float[path.positions.Length]; int nv = 8 * (method - 1); if (method == 1) nv = 4; if (method == 0) nv = 1; int p = 0; foreach (LinkedList<GCodePoint> points in path.pointsLists) { if (points.Count < 2) continue; foreach (GCodePoint pt in points) { computeColor(pt.dist); for (int j = 0; j < nv; j++) { cp[p++] = curColor[0]; cp[p++] = curColor[1]; cp[p++] = curColor[2]; } } } GL.Enable(EnableCap.ColorMaterial); GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse); if (colbufSize < cp.Length) { if (colbufSize != 0) GL.DeleteBuffers(1, colbuf); GL.GenBuffers(1, colbuf); colbufSize = cp.Length; GL.BindBuffer(BufferTarget.ArrayBuffer, colbuf[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(cp.Length * sizeof(float) * 2), (IntPtr)0, BufferUsageHint.StaticDraw); } GL.BindBuffer(BufferTarget.ArrayBuffer, colbuf[0]); GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (IntPtr)(cp.Length * sizeof(float)), cp); GL.ColorPointer(3, ColorPointerType.Float, 0, 0); } if (method == 0) { GL.BindBuffer(BufferTarget.ElementArrayBuffer, path.buf[2]); GL.DrawElements(BeginMode.Lines, path.elementsLength, DrawElementsType.UnsignedInt, 0); } else { GL.EnableClientState(ArrayCap.NormalArray); GL.BindBuffer(BufferTarget.ArrayBuffer, path.buf[1]); GL.NormalPointer(NormalPointerType.Float, 0, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, path.buf[2]); GL.DrawElements(BeginMode.Quads, path.elementsLength, DrawElementsType.UnsignedInt, 0); GL.DisableClientState(ArrayCap.NormalArray); } if (liveView && path.lastDist > minHotDist) { GL.Disable(EnableCap.ColorMaterial); GL.DisableClientState(ArrayCap.ColorArray); } GL.DisableClientState(ArrayCap.VertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { if (path.drawMethod != method || recompute || path.hasBuf) path.UpdateVBO(false); if (Main.threeDSettings.drawMethod > 0) // Is also fallback for vbos with dynamic colors { GL.EnableClientState(ArrayCap.VertexArray); if (path.elements == null) return; GL.VertexPointer(3, VertexPointerType.Float, 0, path.positions); float[] cp; if (liveView && path.lastDist > minHotDist) { GL.EnableClientState(ArrayCap.ColorArray); cp = new float[path.positions.Length]; int nv = 8 * (method - 1); if (method == 1) nv = 4; if (method == 0) nv = 1; int p = 0; foreach (LinkedList<GCodePoint> points in path.pointsLists) { foreach (GCodePoint pt in points) { computeColor(pt.dist); for (int j = 0; j < nv; j++) { cp[p++] = curColor[0]; cp[p++] = curColor[1]; cp[p++] = curColor[2]; } } } GL.Enable(EnableCap.ColorMaterial); GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse); GL.ColorPointer(3, ColorPointerType.Float, 0, cp); } if (method == 0) GL.DrawElements(BeginMode.Lines, path.elementsLength, DrawElementsType.UnsignedInt, path.elements); else { GL.EnableClientState(ArrayCap.NormalArray); GL.NormalPointer(NormalPointerType.Float, 0, path.normals); GL.DrawElements(BeginMode.Quads, path.elementsLength, DrawElementsType.UnsignedInt, path.elements); GL.DisableClientState(ArrayCap.NormalArray); } /*ErrorCode err = GL.GetError(); if (err != ErrorCode.NoError) { PrinterConnection.logInfo("D1 error" + err); }*/ if (liveView && path.lastDist > minHotDist) { GL.Disable(EnableCap.ColorMaterial); GL.DisableClientState(ArrayCap.ColorArray); } GL.DisableClientState(ArrayCap.VertexArray); } else { if (!liveView || path.lastDist < minHotDist) { int i, l = path.elementsLength; if (method == 0) { GL.Begin(BeginMode.Lines); for (i = 0; i < l; i++) { int p = path.elements[i] * 3; GL.Vertex3(ref path.positions[p]); } GL.End(); } else { GL.Begin(BeginMode.Quads); for (i = 0; i < l; i++) { int p = path.elements[i] * 3; GL.Normal3(ref path.normals[p]); GL.Vertex3(ref path.positions[p]); } GL.End(); } } else { if (method > 0) { int nv = 8 * (method - 1), i; if (method == 1) nv = 4; float alpha, dalpha = (float)Math.PI * 2f / nv; float[] dir = new float[3]; float[] dirs = new float[3]; float[] diru = new float[3]; float[] n = new float[3]; float dh = 0.5f * h; float dw = 0.5f * w; if (path.pointsCount < 2) return; GL.Begin(BeginMode.Quads); bool first = true; Vector3 last = new Vector3(); foreach (LinkedList<GCodePoint> points in path.pointsLists) { first = true; foreach (GCodePoint pt in points) { Vector3 v = pt.p; setColor(pt.dist); if (first) { last = v; first = false; continue; } bool isLast = pt == points.Last.Value; dir[0] = v.X - last.X; dir[1] = v.Y - last.Y; dir[2] = v.Z - last.Z; if (!fixedH) { float dist = (float)Math.Sqrt(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]); if (dist > 0) { h = (float)Math.Sqrt((pt.e - laste) * dfac / dist); w = h * wfac; dh = 0.5f * h; dw = 0.5f * w; } } normalize(ref dir); dirs[0] = -dir[1]; dirs[1] = dir[0]; dirs[2] = dir[2]; diru[0] = diru[1] = 0; diru[2] = 1; alpha = 0; float c = (float)Math.Cos(alpha) * dh; float s = (float)Math.Sin(alpha) * dw; n[0] = (float)(s * dirs[0] + c * diru[0]); n[1] = (float)(s * dirs[1] + c * diru[1]); n[2] = (float)(s * dirs[2] + c * diru[2]); normalize(ref n); GL.Normal3(n[0], n[1], n[2]); for (i = 0; i < nv; i++) { GL.Vertex3(last.X + s * dirs[0] + c * diru[0], last.Y + s * dirs[1] + c * diru[1], last.Z - dh + s * dirs[2] + c * diru[2]); GL.Vertex3(v.X + s * dirs[0] + c * diru[0], v.Y + s * dirs[1] + c * diru[1], v.Z - dh + s * dirs[2] + c * diru[2]); alpha += dalpha; c = (float)Math.Cos(alpha) * dh; s = (float)Math.Sin(alpha) * dw; n[0] = (float)(s * dirs[0] + c * diru[0]); n[1] = (float)(s * dirs[1] + c * diru[1]); n[2] = (float)(s * dirs[2] + c * diru[2]); normalize(ref n); GL.Normal3(n[0], n[1], n[2]); GL.Vertex3(v.X + s * dirs[0] + c * diru[0], v.Y + s * dirs[1] + c * diru[1], v.Z - dh + s * dirs[2] + c * diru[2]); GL.Vertex3(last.X + s * dirs[0] + c * diru[0], last.Y + s * dirs[1] + c * diru[1], last.Z - dh + s * dirs[2] + c * diru[2]); } last = v; } } GL.End(); } else if (method == 0) { // Draw edges if (path.pointsCount < 2) return; GL.Material(MaterialFace.Front, MaterialParameter.Emission, defaultColor); GL.Begin(BeginMode.Lines); bool first = true; foreach (LinkedList<GCodePoint> points in path.pointsLists) { first = true; foreach (GCodePoint pt in points) { Vector3 v = pt.p; if (liveView && pt.dist >= minHotDist) { float fak = (totalDist - pt.dist) / hotFilamentLength; // 1 = default 0 = hot float fak2 = 1 - fak; curColor[0] = defaultColor[0] * fak + hotColor[0] * fak2; curColor[1] = defaultColor[1] * fak + hotColor[1] * fak2; curColor[2] = defaultColor[2] * fak + hotColor[2] * fak2; GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, curColor); } GL.Vertex3(v); if (!first && pt != points.Last.Value) GL.Vertex3(v); first = false; } } GL.End(); } } } } }
/// <summary> /// Used to mark a section of the path. Is called after drawSegment so VBOs are already /// computed. Not used inside live preview. /// </summary> /// <param name="path"></param> /// <param name="mstart"></param> /// <param name="mend"></param> public void drawSegmentMarked(GCodePath path, int mstart, int mend) { // Check if inside mark area int estart = 0; int eend = path.elementsLength; GCodePoint lastP = null, startP = null, endP = null; foreach (LinkedList<GCodePoint> plist in path.pointsLists) { if (plist.Count > 1) foreach (GCodePoint point in plist) { if (startP == null) { if (point.fline >= mstart && point.fline <= mend) startP = point; } else { if (point.fline > mend) { endP = point; break; } } lastP = point; } if (endP != null) break; } if (startP == null) return; estart = startP.element; if (endP != null) eend = endP.element; if (estart == eend) return; if (Main.threeDSettings.drawMethod == 2) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.AmbientAndDiffuse, defaultColor); GL.EnableClientState(ArrayCap.VertexArray); if (path.elements == null) return; GL.BindBuffer(BufferTarget.ArrayBuffer, path.buf[0]); GL.VertexPointer(3, VertexPointerType.Float, 0, 0); if (method == 0) { GL.BindBuffer(BufferTarget.ElementArrayBuffer, path.buf[2]); GL.DrawElements(BeginMode.Lines, eend - estart, DrawElementsType.UnsignedInt, sizeof(int) * estart); } else { GL.EnableClientState(ArrayCap.NormalArray); GL.BindBuffer(BufferTarget.ArrayBuffer, path.buf[1]); GL.NormalPointer(NormalPointerType.Float, 0, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, path.buf[2]); //GL.DrawElements(BeginMode.Quads, path.elementsLength, DrawElementsType.UnsignedInt, 0); //GL.DrawRangeElements(BeginMode.Quads, estart, eend, path.elementsLength, DrawElementsType.UnsignedInt, 0); GL.DrawElements(BeginMode.Quads, eend - estart, DrawElementsType.UnsignedInt, sizeof(int) * estart); GL.DisableClientState(ArrayCap.NormalArray); } GL.DisableClientState(ArrayCap.VertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { if (path.drawMethod != method || recompute || path.hasBuf) path.UpdateVBO(false); if (Main.threeDSettings.drawMethod > 0) // Is also fallback for vbos with dynamic colors { GL.EnableClientState(ArrayCap.VertexArray); if (path.elements == null) return; GL.VertexPointer(3, VertexPointerType.Float, 0, path.positions); GCHandle handle = GCHandle.Alloc(path.elements, GCHandleType.Pinned); try { IntPtr pointer = new IntPtr(handle.AddrOfPinnedObject().ToInt32() + sizeof(int) * estart); if (method == 0) GL.DrawElements(BeginMode.Lines, eend - estart, DrawElementsType.UnsignedInt, pointer); else { GL.EnableClientState(ArrayCap.NormalArray); GL.NormalPointer(NormalPointerType.Float, 0, path.normals); GL.DrawElements(BeginMode.Quads, eend - estart, DrawElementsType.UnsignedInt, pointer); GL.DisableClientState(ArrayCap.NormalArray); } } finally { if (handle.IsAllocated) { handle.Free(); } } GL.DisableClientState(ArrayCap.VertexArray); } else { int i, l = path.elementsLength; if (method == 0) { GL.Begin(BeginMode.Lines); for (i = estart; i < eend; i++) { int p = path.elements[i] * 3; GL.Vertex3(ref path.positions[p]); } GL.End(); } else { GL.Begin(BeginMode.Quads); for (i = estart; i < eend; i++) { int p = path.elements[i] * 3; GL.Normal3(ref path.normals[p]); GL.Vertex3(ref path.positions[p]); } GL.End(); } } } }