private void push_active_path() { if (ActivePath != null && ActivePath.VertexCount > 1) { if (WantTubeTypes.Contains(ActivePathType)) { append_path_mesh(ActivePath); } } ActivePath = null; }
void push_active_path() { if (ActivePath != null && ActivePath.VertexCount > 1) { if (ActivePathType == ToolpathTypes.Deposition) { append_path_mesh(ActivePath); } } ActivePath = null; }
public void BeginTravel() { var newPath = new PolyLine3d(); if (ActivePath != null && ActivePath.VertexCount > 0) { newPath.AppendVertex(ActivePath.End); } push_active_path(); ActivePath = newPath; ActivePathType = ToolpathTypes.Travel; }
public bool Load(StreamReader sr) { try { int numplys = int.Parse(sr.ReadLine()); for (int c = 0; c < numplys; c++) { PolyLine3d pl = new PolyLine3d(); pl.Load(sr); m_segments.Add(pl); } return(true); } catch (Exception) { return(false); } }
/* * This function takes in a list of polygons along with a z height. * What is returns is an ArrayList of 3d line segments. These line segments correspond * to the intersection of a plane through the polygons. Each polygon may return 0 or 1 line intersections * on the 2d XY plane * I beleive I can determine the winding order (inside or outside facing), based off of the polygon normal */ public List <PolyLine3d> GetZIntersections(List <Polygon> polys, float zcur) { try { List <PolyLine3d> lstlines = new List <PolyLine3d>(); foreach (Polygon poly in polys) { PolyLine3d s3d = poly.IntersectZPlane(zcur); if (s3d != null) { lstlines.Add(s3d); } } return(lstlines); } catch (Exception) { return(null); } }
void append_path_mesh(PolyLine3d pathLine) { TubeGenerator tubegen = new TubeGenerator() { Vertices = new List <Vector3d>(pathLine.Vertices), Polygon = TubeProfile, ClosedLoop = false, Capped = true, NoSharedVertices = true }; DMesh3 tubeMesh = tubegen.Generate().MakeDMesh(); List <DMesh3> layerList; if (LayerMeshes.TryGetValue(ActivePath[0].z, out layerList) == false) { layerList = new List <DMesh3>(); LayerMeshes[ActivePath[0].z] = layerList; } layerList.Add(tubeMesh); }
/* * This function takes in a list of polygons along with a z height. * What is returns is an ArrayList of 3d line segments. These line segments correspond * to the intersection of a plane through the polygons. Each polygon may return 0 or 1 line intersections * on the 2d XY plane */ public ArrayList GetZIntersections(ArrayList polys, double zcur) { try { ArrayList lstlines = new ArrayList(); foreach (Polygon poly in polys) { PolyLine3d s3d = poly.IntersectZPlane(zcur); if (s3d != null) { lstlines.Add(s3d); } } return(lstlines); } catch (Exception) { return(null); } }
public void SetParent(PolyLine3d parent) { m_parent = parent; p1.m_parent = parent; p2.m_parent = parent; }
/// <summary> /// This function will iterate through the optimized loops /// and determine if they are interior or exterior and tag them appropriately /// </summary> /* * public void DetermineInteriorExterior(SliceBuildConfig config) * { * List<PolyLine3d> allsegments = new List<PolyLine3d>(); * foreach (PolyLine3d pln in m_opsegs) * { * pln.tag = PolyLine3d.TAG_INTERIOR; // mark it as interior * List<PolyLine3d> segments = pln.Split(); // split them, retaining the parent * allsegments.AddRange(segments); * } * List<Line2d> lines2d = Get2dLines(config, allsegments); * // 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 * { * // the first point is always an exterior - really? why? * Point2d p1 = (Point2d)points[cnt]; * if (p1.m_parent != null) * { * p1.m_parent.tag = PolyLine3d.TAG_EXTERIOR; // mark as exterior * } * // the second point could be an exterior or interior * Point2d p2 = (Point2d)points[cnt + 1]; * } * } * else // flag error * { * DebugLogger.Instance().LogRecord("Row y=" + y + " odd # of points = " + points.Count + " - Model may have holes"); * } * }// for y = startminY to endY * } */ /// <summary> /// This function trys to join together the short line segments into /// a set of longer 3d polyines /// The goal here is to determine the interior and exterior lines /// This is going to help us do several things: /// 1) import/export SVG/CLI files /// 2) determine overlapping boundaries for better self-intersecting models /// 3) determine overhangs - by detemining if polylines from other layers intersect vertically or are encapsulated. /// /// The first pass of this algorithm may have to be N^2 search, I'll try /// to change it to log(N) or N as I go along /// </summary> /// public void Optimize() { try { // copy all the polylines in segments into a list List <PolyLine3d> allseg = new List <PolyLine3d>(); //create the final optimize segment list m_opsegs = new List <PolyLine3d>(); // copy the list and clone the polyline segments foreach (PolyLine3d pl in m_segments) { if (!pl.m_points[0].Matches(pl.m_points[pl.m_points.Count - 1])) // discard sements with same beginning and end { allseg.Add(new PolyLine3d(pl)); } } // gotta keep track of lines to remove List <PolyLine3d> removelist = new List <PolyLine3d>(); bool done = false; // matchcount is a counter that tracks how many endpoints we've matched this trip around int matchcount = 0; while (!done) { // set the current line to be the first polyline segement PolyLine3d curline = allseg[0]; //iterate through all the line segments in allsegs for (int cnt = 0; cnt < allseg.Count; cnt++) { PolyLine3d pl = allseg[cnt]; if (cnt != 0) // the first polyline is the one we're always trying to match { // if the last point in the current polyline matches the first point // in the line we're testing, add the second point of the line we're testing // to the end of the current line if (curline.m_points[curline.m_points.Count - 1].Matches(pl.m_points[0])) // case 2 { //if ((curline.m_derived.SharesEdge(pl.m_derived))) { for (int i = 1; i < pl.m_points.Count; i++) { curline.m_points.Add(pl.m_points[i]); } removelist.Add(pl); // add the test line to the list of lines to remove, now that we've used it matchcount++; } } else if (curline.m_points[curline.m_points.Count - 1].Matches(pl.m_points[pl.m_points.Count - 1])) // case 4 last point matches last { // && (curline.m_derived.SharesEdge(pl.m_derived)) pl.m_points.Reverse(); for (int i = 1; i < pl.m_points.Count; i++) { curline.m_points.Add(pl.m_points[i]); } removelist.Add(pl); matchcount++; } /* -- SHS: case 1 and case 3 will change the first segment * I need it to calculate correct path direction * else if (curline.m_points[0].Matches(pl.m_points[pl.m_points.Count - 1])) //case 1 * { * curline.m_points.Reverse(); * pl.m_points.Reverse(); * for (int i=1; i<pl.m_points.Count; i++) * curline.m_points.Add(pl.m_points[i]); * removelist.Add(pl); * matchcount++; * } * else if (curline.m_points[0].Matches(pl.m_points[0])) // case 3 * { * curline.m_points.Reverse(); * for (int i = 1; i < pl.m_points.Count; i++) * curline.m_points.Add(pl.m_points[i]); * removelist.Add(pl); * matchcount++; * }*/ } } // now remove all the matched segments from all segment list foreach (PolyLine3d seg in removelist) { allseg.Remove(seg); } removelist.Clear(); if (matchcount > 0) { matchcount = 0; // reset the match counter } else { // the current segment is not longer matching // match curve direction based on normal such that the right side is inside the object. double curveDir = Math.Atan2(curline.m_points[1].y - curline.m_points[0].y, curline.m_points[1].x - curline.m_points[0].x); double normalDir = Math.Atan2(curline.m_derived.m_normal.y, curline.m_derived.m_normal.x); double dirDiff = curveDir - normalDir; if (dirDiff < 0) { dirDiff += 2 * Math.PI; // handle negative result } if ((dirDiff > 0) && (dirDiff < Math.PI)) { curline.m_points.Reverse(); // reverse curve direction to match normal } // add it to the final list of optimized segments m_opsegs.Add(curline); //and remove it from the list of all segments allseg.Remove(curline); //check for end condition if (allseg.Count == 0) { done = true; } } } } catch (Exception ex) { DebugLogger.Instance().LogError(ex.Message); } RemoveDoublePoints(); // make really clean }
public void Begin() { LayerMeshes = new Dictionary <double, List <DMesh3> >(); ActivePath = new PolyLine3d(); }
void discard_active_path() { ActivePath = null; }
public UnsupportedRegions(PolyLine3d p) { ply = p; }
StreamWriter GenerateSVG(List <PolyLine3d> lstPoly, bool isFillPoly) { MemoryStream ms = new MemoryStream(); StreamWriter sw = new StreamWriter(ms); double width = UVDLPApp.Instance().m_printerinfo.m_PlatXSize; double height = UVDLPApp.Instance().m_printerinfo.m_PlatYSize; sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); sw.WriteLine("<!-- Created with CreationWorkshop (http://www.envisionlabs.net/) -->"); sw.WriteLine(); sw.WriteLine("<svg width=\"{0}mm\" height=\"{1}mm\" viewBox=\"{2} {3} {0} {1}\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">", width, height, -width / 2, -height / 2); if (isFillPoly) { // sort polygons into display layers int[] dispLevel = new int[lstPoly.Count]; int i, j, k; int maxLevel = 0; for (i = 0; i < lstPoly.Count; i++) { dispLevel[i] = 0; for (j = 0; j < lstPoly.Count; j++) { if (j == i) { continue; } if (lstPoly[j].PointInPoly2D(lstPoly[i].m_points[0].x, lstPoly[i].m_points[0].y)) { dispLevel[i]++; } } if (dispLevel[i] > maxLevel) { maxLevel = dispLevel[i]; } } // draw polygons layer by layer for (k = 0; k <= maxLevel; k++) { for (j = 0; j < lstPoly.Count; j++) { if (dispLevel[j] != k) { continue; } PolyLine3d pl = lstPoly[j]; int plen = pl.m_points.Count; if (pl.m_points[0].Matches(pl.m_points[plen - 1])) { plen--; // no need for last point if it matches the firat } // determine polygon direction float dir = 0; for (i = 1; i < plen; i++) { dir += (pl.m_points[i].x - pl.m_points[i - 1].x) * (pl.m_points[i].y + pl.m_points[i - 1].y); } dir += (pl.m_points[0].x - pl.m_points[plen - 1].x) * (pl.m_points[0].y + pl.m_points[plen - 1].y); // draw polygon sw.Write("<polygon points=\""); for (i = 0; i < plen; i++) { sw.Write("{0},{1}", pl.m_points[i].x, -pl.m_points[i].y); if (i < (plen - 1)) { sw.Write(" "); } } sw.WriteLine("\" style=\"fill:{0}\" />", dir < 0 ? "black" : "white"); // - for some resaon it seems // that polygon direction does not work properly so i use layer level instead. //sw.WriteLine("\" style=\"fill:{0}\" />", (k & 1) == 1 ? "black" : "white"); } } } else { sw.Write("<path d=\""); foreach (PolyLine3d pl in lstPoly) { int plen = pl.m_points.Count; if (pl.m_points[0].Matches(pl.m_points[plen - 1])) { plen--; // no need for last point if it matches the firat } for (int i = 0; i < plen; i++) { if (i == 0) { sw.Write("M{0} {1} ", pl.m_points[i].x, -pl.m_points[i].y); } else { sw.Write("L{0} {1} ", pl.m_points[i].x, -pl.m_points[i].y); } } sw.WriteLine("Z "); } sw.WriteLine("\" />"); } //<path d="M 15 2 L9.5 18.0 L25.5 22.0 Z M 15.0 0 L7.5 20.0 L22.5 20.0 Z" fill-rule="evenodd"/> sw.WriteLine("</svg>"); sw.Flush(); sw.BaseStream.Seek(0, SeekOrigin.Begin); return(sw); }
/// <summary> /// This function trys to join together the short line segments into /// a set of longer 3d polyines /// The goal here is to determine the interior and exterior lines /// This is going to help us do several things: /// 1) import/export SVG/CLI files /// 2) determine overlapping boundaries for better self-intersecting models /// 3) determine overhangs - by detemining if polylines from other layers intersect vertically or are encapsulated. /// /// The first pass of this algorithm may have to be N^2 search, I'll try /// to change it to log(N) or N as I go along /// </summary> /// public void Optimize() { try { // copy all the polylines in segments into a list List <PolyLine3d> allseg = new List <PolyLine3d>(); //create the final optimize segment list m_opsegs = new List <PolyLine3d>(); // copy the list and clone the polyline segments foreach (PolyLine3d pl in m_segments) { allseg.Add(new PolyLine3d(pl)); } // gotta keep track of lines to remove List <PolyLine3d> removelist = new List <PolyLine3d>(); bool done = false; // matchcount is a counter that tracks how many endpoints we've matched this trip around int matchcount = 0; while (!done) { // set the current line to be the first polyline segement PolyLine3d curline = allseg[0]; //iterate through all the line segments in allsegs for (int cnt = 0; cnt < allseg.Count; cnt++) { PolyLine3d pl = allseg[cnt]; if (cnt != 0) // the first polyline is the one we're always trying to match { // if the last point in the current polyline matches the first point // in the line we're testing, add the second point of the line we're testing // to the end of the current line if (curline.m_points[curline.m_points.Count - 1].Matches(pl.m_points[0])) // case 2 { //if ((curline.m_derived.SharesEdge(pl.m_derived))) { curline.m_points.AddRange(pl.m_points); removelist.Add(pl); // add the test line to the list of lines to remove, now that we've used it matchcount++; } } else if (curline.m_points[curline.m_points.Count - 1].Matches(pl.m_points[pl.m_points.Count - 1])) // case 4 last point matches last { // && (curline.m_derived.SharesEdge(pl.m_derived)) pl.m_points.Reverse(); curline.m_points.AddRange(pl.m_points); removelist.Add(pl); matchcount++; } else if (curline.m_points[0].Matches(pl.m_points[pl.m_points.Count - 1])) //case 1 { curline.m_points.Reverse(); pl.m_points.Reverse(); curline.m_points.AddRange(pl.m_points); removelist.Add(pl); matchcount++; } else if (curline.m_points[0].Matches(pl.m_points[0])) // case 3 { curline.m_points.Reverse(); curline.m_points.AddRange(pl.m_points); removelist.Add(pl); matchcount++; } } } // now remove all the matched segments from all segment list foreach (PolyLine3d seg in removelist) { allseg.Remove(seg); } removelist.Clear(); if (matchcount > 0) { matchcount = 0; // reset the match counter } else { // the current segment is not longer matching // add it to the final list of optimized segments m_opsegs.Add(curline); //and remove it from the list of all segments allseg.Remove(curline); //check for end condition if (allseg.Count == 0) { done = true; } } } } catch (Exception ex) { DebugLogger.Instance().LogError(ex.Message); } RemoveDoublePoints(); // make really clean }