public void Join(GCodePath path) { foreach (LinkedList<GCodePoint> frag in path.pointsLists) { pointsLists.AddLast(frag); } pointsCount += path.pointsCount; if (elements != null && path.elements != null) { if (/*normals!=null && */path.elements != null && drawMethod == path.drawMethod) // both parts are already up to date, so just join them { int[] newelements = new int[elementsLength + path.elementsLength]; int p, l = elementsLength, i; for (p = 0; p < l; p++) newelements[p] = elements[p]; int[] pe = path.elements; l = path.elementsLength; int pointsold = positions.Length / 3; for (i = 0; i < l; i++) newelements[p++] = pe[i] + pointsold; elements = newelements; elementsLength = elements.Length; float[] newnormals = null; if (normals != null) newnormals = new float[normals.Length + path.normals.Length]; float[] newpoints = new float[positions.Length + path.positions.Length]; if (normals != null) { l = normals.Length; for (p = 0; p < l; p++) { newnormals[p] = normals[p]; newpoints[p] = positions[p]; } float[] pn = path.normals; float[] pp = path.positions; l = pp.Length; for (i = 0; i < l; i++) { newnormals[p] = pn[i]; newpoints[p++] = pp[i]; } normals = newnormals; positions = newpoints; } else { l = positions.Length; for (p = 0; p < l; p++) { newpoints[p] = positions[p]; } float[] pp = path.positions; l = pp.Length; for (i = 0; i < l; i++) { newpoints[p++] = pp[i]; } positions = newpoints; } } else { elements = null; normals = null; positions = null; drawMethod = -1; } if (hasBuf) { GL.DeleteBuffers(3, buf); hasBuf = false; } } else { drawMethod = -1; } }
void OnPosChangeFast(float x, float y, float z, float e) { if (!ana.drawing || ana.layer < minLayer || ana.layer > maxLayer) { lastx = x; lasty = y; lastz = z; laste = ana.emax; lastLayer = ana.layer; return; } float locDist = (float)Math.Sqrt((x - lastx) * (x - lastx) + (y - lasty) * (y - lasty) + (z - lastz) * (z - lastz)); bool isLastPos = locDist < 0.00001; int segpos = ana.activeExtruder; if (ana.eChanged == false) { GCodeTravel travel = new GCodeTravel(); travel.fline = GCodePoint.toFileLine(fileid, actLine); travel.p1.X = lastx; travel.p1.Y = lasty; travel.p1.Z = lastz; travel.p2.X = x; travel.p2.Y = y; travel.p2.Z = z; travelMoves.Add(travel); } if (segpos < 0 || segpos >= MaxExtruder) segpos = 0; LinkedList<GCodePath> seg = segments[segpos]; //if (!act.hasG || (act.G > 1 && act.G != 28)) return; if (lastLayer == minLayer - 1 && laste < e) { GCodePath p = new GCodePath(); p.Add(new Vector3(lastx, lasty, lastz), laste, totalDist, GCodePoint.toFileLine(fileid, actLine)); if (seg.Count > 0 && seg.Last.Value.pointsLists.Last.Value.Count == 1) { seg.RemoveLast(); } seg.AddLast(p); } if (seg.Count == 0 || laste >= ana.e) // start new segment { if (!isLastPos) // no move, no action { GCodePath p = new GCodePath(); p.Add(new Vector3(x, y, z), ana.emax, totalDist, GCodePoint.toFileLine(fileid, actLine)); if (seg.Count > 0 && seg.Last.Value.pointsLists.Last.Value.Count == 1) { seg.RemoveLast(); } seg.AddLast(p); //changed = true; } } else { if (!isLastPos) { totalDist += locDist; seg.Last.Value.Add(new Vector3(x, y, z), ana.emax, totalDist, GCodePoint.toFileLine(fileid, actLine)); //changed = true; } } lastx = x; lasty = y; lastz = z; laste = ana.emax; lastLayer = ana.layer; }
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(); } } } }