/// <summary> /// Adds a new dummy support /// </summary> public void AddSupport() { // Cylinder3d cyl = new Cylinder3d(); // cyl.Create(2.5, 1.5, 10, 15, 2); Support s = new Support(); //s.Create((float)m_supportconfig.fbrad, 1.5f, 1.5f, .75f, 2f, 5f, 2f, 20); s.Create(null,(float)m_supportconfig.fbrad, (float)m_supportconfig.ftrad, (float)m_supportconfig.hbrad, (float)m_supportconfig.htrad, 2f, 5f, 2f, 11); m_engine3d.AddObject(s); UVDLPApp.Instance().m_undoer.SaveAddition(s); RaiseAppEvent(eAppEvent.eModelAdded, "Model Created"); }
public bool Load(string scenename) { try { ZipFile zip = ZipFile.Read(scenename); string xmlname = "manifest.xml"; ZipEntry manifestentry = zip[xmlname]; //create new manifest xml doc XmlHelper manifest = new XmlHelper(); //get memory stream MemoryStream manistream = new MemoryStream(); //extract the stream manifestentry.Extract(manistream); //read from stream manistream.Seek(0, SeekOrigin.Begin); // rewind the stream for reading manifest.LoadFromStream(manistream, "manifest"); //examine manifest //find the node with models XmlNode topnode = manifest.m_toplevel; XmlNode models = manifest.FindSection(topnode, "Models"); List<XmlNode> modelnodes = manifest.FindAllChildElement(models, "model"); foreach (XmlNode nd in modelnodes) { string name = manifest.GetString(nd, "name", "noname"); string modstlname = name + ".stl"; int tag = manifest.GetInt(nd, "tag", 0); ZipEntry modelentry = zip[modstlname]; // the model name will have the _XXXX on the end with the stl extension MemoryStream modstr = new MemoryStream(); modelentry.Extract(modstr); //rewind to beginning modstr.Seek(0, SeekOrigin.Begin); //fix the name name = name.Substring(0, name.Length - 5);// get rid of the _XXXX at the end if (tag == Object3d.OBJ_SUPPORT) { Support s = new Support(); //load the model s.LoadSTL_Binary(modstr, name); //add to the 3d engine UVDLPApp.Instance().m_engine3d.AddObject(s); //set the tag s.tag = tag; string parent = manifest.GetString(nd, "parent", "noname"); s.SetColor(System.Drawing.Color.Yellow); //find and set the parent Object3d tmp = UVDLPApp.Instance().m_engine3d.Find(parent); if (tmp != null) { tmp.AddSupport(s); } } else { //load as normal object Object3d obj = new Object3d(); //load the model obj.LoadSTL_Binary((MemoryStream)modstr, name); //add to the 3d engine UVDLPApp.Instance().m_engine3d.AddObject(obj); //set the tag obj.tag = tag; } } return true; } catch (Exception ex) { DebugLogger.Instance().LogError(ex); return false; } }
public List<Object3d> GenerateSupportObjects() { // iterate over the platform size by indicated mm step; // projected resolution in x,y // generate a 3d x/y point on z=0, // generate another on the z=zmax // use this ray to intersect the scene // foreach intersection point, generate a support // we gott make sure supports don't collide // I also have to take into account the // interface between the support and the model List<Object3d> lstsupports = new List<Object3d>(); float ZVal = (float)UVDLPApp.Instance().m_printerinfo.m_PlatZSize; m_model.Update(); float MinX = m_model.m_min.x; float MaxX = m_model.m_max.x; float MinY = m_model.m_min.y; float MaxY = m_model.m_max.y; // bool intersected = false; int scnt = 0; // support count // iterate from -HX to HX step xtep; double dts = (MaxX - MinX) / m_sc.xspace; int its = (int)dts; int curstep = 0; for (float x = (float)(MinX + (m_sc.xspace / 2.0f)); x < MaxX; x += (float)m_sc.xspace) { // say we're doing stuff RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eProgress, "" + curstep + "/" + its, null); curstep++; for (float y = (float)(MinY + (m_sc.yspace / 2)); y < MaxY; y += (float)m_sc.yspace) { Point3d origin; origin = new Point3d(); // bottom point origin.Set(x, y, 0.0f); //intersected = false; // reset the intersected flag to be false Vector3d up = new Vector3d(); // the up vector up.x = 0.0f; up.y = 0.0f; up.z = 1.0f; List<ISectData> lstISects = RTUtils.IntersectObjects(up, origin, UVDLPApp.Instance().Engine3D.m_objects, false); //check for cancelling if (m_cancel) { RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCancel, "Support Generation Cancelled", null); return lstsupports; } foreach (ISectData htd in lstISects) { if (htd.obj.tag != Object3d.OBJ_SUPPORT) // if this is not another support or the ground { if (htd.obj.tag != Object3d.OBJ_GROUND) // if it's not the ground { if (m_sc.m_onlydownward && htd.poly.tag != Polygon.TAG_MARKDOWN) break; // not a downward facing and we're only doing downward // this should be the closest intersected Support s = new Support(); float lz = (float)htd.intersect.z; s.Create((float)m_sc.fbrad, (float)m_sc.ftrad, (float)m_sc.hbrad, (float)m_sc.htrad, lz * .2f, lz * .6f, lz * .2f, 11); s.Translate((float)x, (float)y, 0); s.Name = "Support " + scnt; s.SetColor(Color.Yellow); scnt++; lstsupports.Add(s); RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s); break; // only need to make one support } } } } } // return objects; RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCompleted, "Support Generation Completed", lstsupports); m_generating = false; return lstsupports; }
void AddNewSupport(float x, float y, float lz, int scnt, Object3d parent, List<Object3d> lstsupports) { Support s = new Support(); s.Create(parent, (float)m_sc.fbrad, (float)m_sc.ftrad, (float)m_sc.hbrad, (float)m_sc.htrad, lz * .2f, lz * .6f, lz * .2f, 11); s.Translate(x, y, 0); s.Name = "Support " + scnt; s.SetColor(Color.Yellow); lstsupports.Add(s); if (parent != null) parent.AddSupport(s); RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s); }
Support AddNewSupport(float x, float y, float lz, Object3d parent) { Support s = new Support(); Configs.SupportConfig sc = UVDLPApp.Instance().m_supportconfig; //s.Create(sc,parent, (float)sc.fbrad, (float)sc.ftrad, (float)sc.hbrad, (float)sc.htrad, lz * .2f, lz * .6f, lz * .2f, 11); s.Create(sc, parent, lz * .2f, lz * .6f, lz * .2f); s.Translate(x, y, 0); s.SetColor(Color.Yellow); if (parent != null) parent.AddSupport(s); UVDLPApp.Instance().m_engine3d.AddObject(s); UVDLPApp.Instance().SelectedObject = s; //RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s); UVDLPApp.Instance().RaiseAppEvent(eAppEvent.eModelAdded, ""); return s; }
/// <summary> /// This is the adaptive support generation, it should automatically /// detect overhangs, /// The way that it does this is by generating a closed polyline loop for each layer /// and checking the 2d projection of the current layer with the previous layer /// </summary> public void GenerateAdaptive() { //iterate through all the layers starting from z=0 // check every polyline in the current layer to make sure it is encased or overlaps polylines in the previous layer // generate a list of unsupported polylines // 'check' to see if the polyline can be dropped straight down // this has to do slicing of the scene try { SliceBuildConfig config = UVDLPApp.Instance().m_buildparms; config.UpdateFrom(UVDLPApp.Instance().m_printerinfo); // make sure we've got the correct display size and PixPerMM values if (UVDLPApp.Instance().m_slicer.SliceFile == null) { SliceFile sf = new SliceFile(config); sf.m_mode = SliceFile.SFMode.eImmediate; UVDLPApp.Instance().m_slicer.SliceFile = sf; // wasn't set } List<UnsupportedRegions> lstunsup = new List<UnsupportedRegions>(); List<Object3d> lstsupports = new List<Object3d>(); // final list of supports int numslices = UVDLPApp.Instance().m_slicer.GetNumberOfSlices(config); float zlev = 0.0f; Slice curslice = null; Slice prevslice = null; int hxres = config.xres / 2; int hyres = config.yres / 2; for (int c = 0; c < numslices; c++) { //bool layerneedssupport = false; if (m_cancel) { RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCancel, "Support Generation Cancelled", null); return; } RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eProgress, "" + c + "/" + numslices, null); Slice sl = UVDLPApp.Instance().m_slicer.GetSliceImmediate(zlev); zlev += (float)config.ZThick; if (sl == null) continue; if (sl.m_segments == null) continue; if (sl.m_segments.Count == 0) continue; sl.Optimize();// find loops //sl.DetermineInteriorExterior(config); // mark the interior/exterior loops prevslice = curslice; curslice = sl; Bitmap bm = new Bitmap(config.xres, config.yres); using (Graphics gfx = Graphics.FromImage(bm)) using (SolidBrush brush = new SolidBrush(Color.Black)) { gfx.FillRectangle(brush, 0, 0, bm.Width, bm.Height); } if (prevslice != null && curslice != null) { //render current slice curslice.RenderSlice(config, ref bm); //now render the previous slice overtop the current slice in another color Color savecol = UVDLPApp.Instance().m_appconfig.m_foregroundcolor; UVDLPApp.Instance().m_appconfig.m_foregroundcolor = Color.HotPink; //render previous slice over top prevslice.RenderSlice(config, ref bm); UVDLPApp.Instance().m_appconfig.m_foregroundcolor = savecol; // restore the color // create a lock bitmap for faster pixel access LockBitmap lbm = new LockBitmap(bm); lbm.LockBits(); // now, iterate through all optimized polylines in current slice // this approach isn't going to work, we need to iterate through all polyline //segments in a slice at once, each individual segment needs to know 1 thing // 1) the optimized segment it came from //iterate through all optimized polygon segments Dictionary<PolyLine3d, bool> supportmap = new Dictionary<PolyLine3d, bool>(); foreach (PolyLine3d pln in curslice.m_opsegs) { bool plysupported = false; List<PolyLine3d> allsegments = new List<PolyLine3d>(); List<PolyLine3d> segments = pln.Split(); // split them, retaining the parent allsegments.AddRange(segments); //add all optimized polyline segments into the supported map supportmap.Add(pln, true); //split this optimized polyline back into 2-point segments for easier use List<Line2d> lines2d = Get2dLines(config, allsegments); if (lines2d.Count == 0) continue; // find the x/y min/max MinMax_XY mm = Slice.CalcMinMax_XY(lines2d); // iterate from the ymin to the ymax for (int y = mm.ymin; y < mm.ymax; y++) // this needs to be in scaled value { // get a line of lines that intersect this 2d line List<Line2d> intersecting = Slice.GetIntersecting2dYLines(y, lines2d); // get the list of point intersections List<Point2d> points = Slice.GetIntersectingPoints(y, intersecting); // sort the points in increasing x order points.Sort(); if (points.Count % 2 == 0) // is even { for (int cnt = 0; cnt < points.Count; cnt += 2) // increment by 2 { Point2d p1 = (Point2d)points[cnt]; Point2d p2 = (Point2d)points[cnt + 1]; Point pnt1 = new Point(); // create some points for drawing Point pnt2 = new Point(); pnt1.X = (int)(p1.x + config.XOffset + hxres); pnt1.Y = (int)(p1.y + config.YOffset + hyres); pnt2.X = (int)(p2.x + config.XOffset + hxres); pnt2.Y = (int)(p2.y + config.YOffset + hyres); //iterate from pnt1.X to pnt2.x and check colors for (int xc = pnt1.X; xc < pnt2.X; xc++) { if (xc >= lbm.Width || xc <=0 ) continue; if (pnt1.Y >= lbm.Height || pnt1.Y <= 0) continue; try { Color checkcol = lbm.GetPixel(xc, pnt1.Y); // need to check the locked BM here for the right color // if the pixel color is the hot pink, then this region has some support // we're going to need to beef this up and probably divide this all into regions on a grid if (checkcol.R == Color.HotPink.R && checkcol.G == Color.HotPink.G && checkcol.B == Color.HotPink.B) { plysupported = true; } } catch (Exception ex) { DebugLogger.Instance().LogError(ex); } } } } else // flag error { DebugLogger.Instance().LogRecord("Row y=" + y + " odd # of points = " + points.Count + " - Model may have holes"); } }// for y = startminY to endY if (plysupported == false) { // layerneedssupport = true; supportmap[pln] = false; lstunsup.Add(new UnsupportedRegions(pln)); } } // for each optimized polyline lbm.UnlockBits(); // unlock the bitmap } // prev and current slice are not null //if (layerneedssupport) // SaveBM(bm, c); // uncomment this to see the layers that need support } // iterating through all slices // iterate through all unsupported regions // calculate the center // add a support from that region going down to the ground (or closest intersected) int scnt = 0; foreach (UnsupportedRegions region in lstunsup) { Support s = new Support(); Point3d center = region.Center(); float lz = center.z; AddNewSupport(center.x, center.y, center.z, scnt++, null, lstsupports); //region.ply.m_derived. /*s.Create(null,(float)m_sc.fbrad, (float)m_sc.ftrad, (float)m_sc.hbrad, (float)m_sc.htrad, lz * .2f, lz * .6f, lz * .2f, 11); s.Translate((float)center.x, (float)center.y, 0); s.Name = "Support " + scnt; s.SetColor(Color.Yellow); scnt++; lstsupports.Add(s); RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s); */ } RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCompleted, "Support Generation Completed", lstsupports); m_generating = false; } catch (Exception ex) { DebugLogger.Instance().LogError(ex); } }
public Support MakeCopy() { Support obj = new Support(); try { obj.m_name = UVDLPApp.Instance().Engine3D.GetUniqueName(this.m_name); // need to find unique name obj.m_fullname = this.m_fullname; obj.tag = this.tag; foreach (Polygon ply in m_lstpolys) { Polygon pl2 = new Polygon(); pl2.m_color = ply.m_color; pl2.m_points = new Point3d[3]; obj.m_lstpolys.Add(pl2); pl2.m_points[0] = new Point3d(ply.m_points[0]); pl2.m_points[1] = new Point3d(ply.m_points[1]); pl2.m_points[2] = new Point3d(ply.m_points[2]); } foreach (Polygon ply in obj.m_lstpolys) { foreach (Point3d pnt in ply.m_points) { obj.m_lstpoints.Add(pnt); // a fair bit of overlap, but whatever... } } obj.Update(); } catch (Exception ex) { DebugLogger.Instance().LogError(ex); } return obj; }
public void RemoveSupport(Support s) { if (s == null) return; while (m_supports.IndexOf(s) >= 0) m_supports.Remove(s); s.m_parrent = null; }
public void AddSupport(Support s) { if (s == null) return; if (s.m_parrent != null) s.m_parrent.RemoveSupport(s); s.m_parrent = this; if (m_supports.IndexOf(s) < 0) m_supports.Add(s); }
Support AddNewSupport(float x, float y, float zbase, float ztop, int scnt, List<Object3d> lstsupports) { ISectData isectTop = GetIntersection(x, y, ztop); if (isectTop == null) return null; if (m_sc.m_onlydownward) { Vector3d upvec = new Vector3d(); double inc = 1.0 / 90.0; double angle = -(1 - (m_sc.downwardAngle * inc)); upvec.Set(new Point3d(0, 0, 1)); isectTop.poly.CalcNormal(); double d = isectTop.poly.m_normal.Dot(upvec); if (m_sc.m_onlydownward && d >= angle) // this makes sure downward works even if polygons are not tagged return null; } Support s = new Support(); s.Create(m_sc, isectTop.obj, ztop * .2f, ztop * .6f, ztop * .2f); s.Translate(x, y, 0); s.SelectionType = Support.eSelType.eTip; s.MoveFromTip(isectTop); if (zbase > 0) { ISectData isectBase = GetIntersection(x, y, zbase); if (isectBase != null) { s.SelectionType = Support.eSelType.eBase; s.SubType = Support.eSubType.eIntra; s.PositionBottom(isectBase); } } s.Name = "Support " + scnt; s.SetColor(Color.Yellow); lstsupports.Add(s); if (isectTop.obj != null) isectTop.obj.AddSupport(s); RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s); return s; }