示例#1
0
 private void push_active_path()
 {
     if (ActivePath != null && ActivePath.VertexCount > 1)
     {
         if (WantTubeTypes.Contains(ActivePathType))
         {
             append_path_mesh(ActivePath);
         }
     }
     ActivePath = null;
 }
示例#2
0
 void push_active_path()
 {
     if (ActivePath != null && ActivePath.VertexCount > 1)
     {
         if (ActivePathType == ToolpathTypes.Deposition)
         {
             append_path_mesh(ActivePath);
         }
     }
     ActivePath = null;
 }
示例#3
0
        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;
        }
示例#4
0
 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);
     }
 }
示例#6
0
        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);
        }
示例#7
0
 /*
  * 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);
     }
 }
示例#8
0
 public void SetParent(PolyLine3d parent)
 {
     m_parent    = parent;
     p1.m_parent = parent;
     p2.m_parent = parent;
 }
示例#9
0
        /// <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
        }
示例#10
0
 public void Begin()
 {
     LayerMeshes = new Dictionary <double, List <DMesh3> >();
     ActivePath  = new PolyLine3d();
 }
示例#11
0
 void discard_active_path()
 {
     ActivePath = null;
 }
 public UnsupportedRegions(PolyLine3d p)
 {
     ply = p;
 }
示例#13
0
        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);
        }
示例#14
0
        /// <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
        }