protected int figureId;                                     // track GCode figure-id

            public PathObject Copy()
            {
                if (this is ItemDot)
                {
                    ItemDot n = new ItemDot(this.Start.X, this.Start.Y);
                    n.info       = this.info.Copy();
                    n.pathLength = this.pathLength;
                    n.distance   = this.distance;
                    n.start      = this.start;
                    n.startAngle = this.startAngle;
                    n.end        = this.end;
                    return(n);
                }
                else
                {
                    ItemPath n = new ItemPath();
                    n.info = this.info.Copy();

                    if (((ItemPath)this).dashArray.Length > 0)
                    {
                        n.dashArray = new double[((ItemPath)this).dashArray.Length];
                        ((ItemPath)this).dashArray.CopyTo(n.dashArray, 0);
                    }

                    foreach (GCodeMotion motion in ((ItemPath)this).path)
                    {
                        if (motion is GCodeLine)
                        {
                            n.AddMotion(new GCodeLine((GCodeLine)motion));
                        }
                        else if (motion is GCodeArc)
                        {
                            n.AddMotion(new GCodeArc((GCodeArc)motion));
                        }
                    }
                    n.pathLength = this.pathLength;
                    n.distance   = this.distance;
                    n.start      = this.start;
                    n.startAngle = this.startAngle;
                    n.end        = this.end;
                    n.dimension  = new Dimensions(this.dimension);
                    return(n);
                }
            }
Пример #2
0
//convert graphic to gcode ##################################################################
        private static void ProcessPathObject(PathObject pathObject, Graphic.GraphicInformation graphicInfo)
        {
            if (logDetailed)
            {
                Logger.Trace("ProcessPathObject start");
            }
            figureEnable = graphicInfo.FigureEnable;
            float origZ = gcode.gcodeZDown;

/* Create Dot */
            if (pathObject is ItemDot)
            {
                ItemDot DotData = (ItemDot)pathObject;
                if (DotData.UseZ)
                {
                    double setZ = calculateZFromRange(graphicInfo.DotZMin, graphicInfo.DotZMax, DotData.Z);//-Math.Abs(DotData.Z);      // be sure for right sign
                    if (logEnable)
                    {
                        Logger.Trace("---Dot DotData.UseZ: RangeMin:{0:0.00}  RangeMax:{1:0.00}  DotData.Z:{2:0.00}  -> setZ:{3:0.00}", graphicInfo.DotZMin, graphicInfo.DotZMax, DotData.Z, setZ);
                    }
                    setZ = Math.Max(origZ, setZ);    // don't go deeper than set Z
                    if (logCoordinates)
                    {
                        Logger.Trace("  PenDownWithZ z:{0:0.00}  setZ:{1:0.00}  gcodeZDown:{2:0.00}", DotData.Z, setZ, origZ);
                    }
                    gcode.gcodeZDown = (float)setZ;
                    penIsDown        = false;
                }

                else if (graphicInfo.OptionZFromWidth)
                {
                    double newZ = calculateZFromRange(graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, DotData.Z);
                    if (logEnable)
                    {
                        Logger.Trace("---Dot OptionZFromWidth: RangeMin:{0:0.00}  RangeMax:{1:0.00}  DotData.Z:{2:0.00}  -> setZ:{3:0.00}", graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, DotData.Z, newZ);
                    }
                    newZ             = Math.Max(origZ, newZ); // don't go deeper than set Z
                    gcode.gcodeZDown = (float)newZ;
                    penIsDown        = false;
                }

                pathObject.FigureId = StartPath(DotData);
                PenDown();
                StopPath();
                gcode.gcodeZDown = origZ;
            }
            else
            {
                if (graphicInfo.OptionZFromWidth)
                {
                    gcode.gcodeZDown = 0;
                }

                ItemPath PathData = (ItemPath)pathObject;
                if (logDetailed)
                {
                    Logger.Trace(" {0}  cnt:{1}", PathData.Info.List(), PathData.path.Count);
                }

                if (PathData.path.Count == 0)
                {
                    if (logEnable)
                    {
                        Logger.Trace("--ProcessPathObject: Empty path ID:{0}", PathData.Info.id);
                    }
                    return;
                }
                pathObject.FigureId = StartPath(PathData);
                PathDashArray       = PathData.dashArray;

                double newZ = gcode.gcodeZDown;                           // default

                for (int index = 1; index < PathData.path.Count; index++) // 0 was already processed in StartPath
                {
                    GCodeMotion entity = PathData.path[index];
                    if (graphicInfo.OptionZFromWidth)
                    {
                        newZ             = calculateZFromRange(graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, entity.Depth);
                        newZ             = Math.Max(origZ, newZ); // don't go deeper than set Z
                        gcode.gcodeZDown = (float)newZ;
                        if (!Properties.Settings.Default.importDepthFromWidthRamp)
                        {
                            penIsDown = false;
                        }
                        if (logEnable)
                        {
                            Logger.Trace("--ProcessPathObject: penWidth:{0:0.00}  -> setZ:{1:0.00}", entity.Depth, newZ);
                        }
                    }

/* Create Line */
                    if (entity is GCodeLine)
                    {
                        MoveTo(entity.MoveTo, newZ, entity.Angle, "");
                    }
                    else if (entity is GCodeArc)
                    {
/* Create Arc */
                        GCodeArc ArcData = (GCodeArc)entity;
                        Arc(ArcData.IsCW, ArcData.MoveTo, ArcData.CenterIJ, newZ, ArcData.AngleStart, ArcData.Angle, "");                        // entity.comment);
                    }
                }
                StopPath("");
            }
            gcode.gcodeZDown = origZ;
            if (logDetailed)
            {
                Logger.Trace("ProcessPathObject end");
            }
        }
Пример #3
0
        public static void CalculateTangentialAxis()
        {
            const uint loggerSelect      = (uint)LogEnable.PathModification;
            double     maxAngleChangeDeg = (double)Properties.Settings.Default.importGCTangentialAngle;
            bool       limitRange        = Properties.Settings.Default.importGCTangentialRange;

            double maxAngleRad = maxAngleChangeDeg * Math.PI / 180;     // in RAD
            double angleNow, angleLast, angleOffset, angleApply, angleLastApply;

            finalPathList = new List <PathObject>();    // figures of one tile
            ItemPath tempPath = new ItemPath();
            Point    pStart, pEnd;

            Logger.Trace("...CalculateTangentialAxis maxAngle:{0}", maxAngleChangeDeg);
            gcodeMath.resetAngles();

            foreach (PathObject graphicItem in completeGraphic)
            {
                angleLast   = angleApply = angleLastApply = 0;
                angleOffset = 0;
                if (!(graphicItem is ItemDot))
                {
                    ItemPath item = (ItemPath)graphicItem;

                    if (item.path.Count == 0)
                    {
                        continue;
                    }

                    pStart = item.path[0].MoveTo;

                    /* copy general info */
                    actualDashArray = new double[0];
                    if (item.dashArray.Length > 0)
                    {
                        actualDashArray = new double[item.dashArray.Length];
                        item.dashArray.CopyTo(actualDashArray, 0);
                    }

                    tempPath = new ItemPath(new Point(pStart.X, pStart.Y));     // create new path
                    tempPath.Info.CopyData(graphicItem.Info);                   // preset global info for GROUP
                    if (actualDashArray.Length > 0)                             // set dash array
                    {
                        tempPath.dashArray = new double[actualDashArray.Length];
                        actualDashArray.CopyTo(tempPath.dashArray, 0);
                    }

                    for (int i = 1; i < item.path.Count; i++)                   // go through path objects
                    {
                        pStart = item.path[i - 1].MoveTo;
                        pEnd   = item.path[i].MoveTo;

                        /* Process Line */
                        if (item.path[i] is GCodeLine)
                        {
                            angleNow = gcodeMath.getAlpha(pStart, pEnd);    // angle-i = p[i-1] to p[i] in radiant

                            //                            if ((loggerTrace & loggerSelect) > 0) Logger.Trace("    TangentialAxis diff:{0:0.00} now:{1:0.00}  last:{2:0.00} offfset:{3:0.00}  ", diff, angleNow,angleLast, angleOffset);

                            if (i == 1)
                            {
                                angleLast           = item.path[0].Angle = angleNow;
                                tempPath.StartAngle = angleNow;
                                angleLastApply      = angleApply = angleNow;
                            }

                            if ((logFlags & loggerSelect) > 0)
                            {
                                Logger.Trace("    before angleNow:{0:0.00}  angleLast:{1:0.00} angleApply:{2:0.00}  offset:{3:0.00}", (angleNow * 180 / Math.PI), (angleLast * 180 / Math.PI), (angleApply * 180 / Math.PI), (angleOffset * 180 / Math.PI));
                            }

                            double diff = angleNow - angleLast; // + angleOffset;
                            if (diff > Math.PI)
                            {
                                angleOffset -= 2 * Math.PI;
                            }
                            else if (diff < -Math.PI)
                            {
                                angleOffset += 2 * Math.PI;
                            }
                            angleApply = angleNow + angleOffset;

                            if ((logFlags & loggerSelect) > 0)
                            {
                                Logger.Trace("    after  angleNow:{0:0.00}  angleLast:{1:0.00} angleApply:{2:0.00}  offset:{3:0.00}", (angleNow * 180 / Math.PI), (angleLast * 180 / Math.PI), (angleApply * 180 / Math.PI), (angleOffset * 180 / Math.PI));
                            }

                            item.path[i].Angle = angleApply;
                            //		if ((loggerTrace & loggerSelect) > 0) Logger.Trace("    TangentialAxis Line   X:{0:0.00} Y:{1:0.00}  end X:{2:0.00} Y:{3:0.00}  angleNow:{4:0.00}  angleApply:{5:0.00}  offset:{6:0.00}", pStart.X, pStart.Y, pEnd.X, pEnd.Y, (angleNow * 180 / Math.PI), (angleApply * 180 / Math.PI), (angleOffset* 180 / Math.PI));

                            /* split path if swivel angle is reached*/
                            if ((Math.Abs(angleLastApply - angleApply) > maxAngleRad) || fixAngleExceed(ref angleApply, ref angleNow, ref angleOffset))         // change in angle is too large -> insert pen up/turn/down -> seperate path
                            {
                                if (tempPath.path.Count > 1)
                                {
                                    finalPathList.Add(tempPath);                // save prev path, start new path to force pen up/turn/down
                                }
                                if ((logFlags & loggerSelect) > 0)
                                {
                                    Logger.Trace("      Exceed angle max:{0:0.00}  actual:{1:0.00}", (maxAngleRad * 180 / Math.PI), (Math.Abs(angleLast - angleNow) * 180 / Math.PI));
                                }

                                tempPath = new ItemPath(new Point(pStart.X, pStart.Y));     // start new path with clipped start position
                                tempPath.Info.CopyData(graphicItem.Info);                   // preset global info for GROUP
                                if (actualDashArray.Length > 0)                             // set dash array
                                {
                                    tempPath.dashArray = new double[actualDashArray.Length];
                                    actualDashArray.CopyTo(tempPath.dashArray, 0);
                                }
                                tempPath.Add(pEnd, item.path[i].Depth, angleApply);
                                tempPath.StartAngle = angleApply;
                            }
                            else
                            {
                                tempPath.Add(pEnd, item.path[i].Depth, angleApply);
                            }                            // add point and angle

                            angleLast      = angleApply; //angleNow;
                            angleLastApply = angleApply;
                        }
                        else
                        /* Process Arc   implement fixAngleExceed(ref angleApply, ref angleNow, ref angleOffset)?*/
                        {
                            double offset = +Math.PI / 2;        // angle-i = center to p[i] + 90° it is the tangente
                            double aStart = 0;
                            if (!((GCodeArc)item.path[i]).IsCW)
                            {
                                offset = -offset;
                            }                                                                                                  // angleStart-i = center to p[i-1] + 90°

                            Point center = new Point(pStart.X + ((GCodeArc)item.path[i]).CenterIJ.X, pStart.Y + ((GCodeArc)item.path[i]).CenterIJ.Y);

                            aStart = gcodeMath.getAngle(pStart, center, offset, 0);     // angle of tangente
                            if (i == 1)
                            {
                                angleLast           = item.path[0].Angle = aStart;
                                tempPath.StartAngle = aStart;
                            }

                            double diff = aStart - angleLast;   // + angleOffset;
                            if (diff > Math.PI)
                            {
                                angleOffset -= 2 * Math.PI;
                            }
                            else if (diff < -Math.PI)
                            {
                                angleOffset += 2 * Math.PI;
                            }
                            angleApply = aStart + angleOffset;

                            //             if (loggerTrace) Logger.Trace(" Tang Circle a-start:{0:0.00} a-end:{1:0.00}  ", (angle * 180 / Math.PI));
                            ((GCodeArc)item.path[i]).AngleStart = angleApply;

                            angleNow = gcodeMath.getAngle(pEnd, center, offset, 0);
                            diff     = angleNow - angleLast;     //+ angleOffset;
                            if (diff > Math.PI)
                            {
                                angleOffset -= 2 * Math.PI;
                            }
                            else if (diff < -Math.PI)
                            {
                                angleOffset += 2 * Math.PI;
                            }
                            angleApply = angleNow + angleOffset;

                            ((GCodeArc)item.path[i]).Angle = angleApply;
                            if ((logFlags & loggerSelect) > 0)
                            {
                                Logger.Trace("    Tangential Circle X:{0:0.00} Y:{1:0.00}  end X:{2:0.00} Y:{3:0.00}  angleStart:{4:0.00} angleEnd:{5:0.00}", pStart.X, pStart.Y, pEnd.X, pEnd.Y, (aStart * 180 / Math.PI), (angleNow * 180 / Math.PI));
                            }

                            if (Math.Abs(angleLast - angleNow) > maxAngleRad)                     // change in angle is too large -> insert pen up/turn/down -> seperate path
                            {
                                if (tempPath.path.Count > 1)
                                {
                                    finalPathList.Add(tempPath);                        // save prev path, start new path to force pen up/turn/down
                                }
                                tempPath = new ItemPath(new Point(pStart.X, pStart.Y)); // start new path with clipped start position
                                tempPath.Info.CopyData(graphicItem.Info);               // preset global info for GROUP
                                if (actualDashArray.Length > 0)
                                {
                                    tempPath.dashArray = new double[actualDashArray.Length];
                                    actualDashArray.CopyTo(tempPath.dashArray, 0);
                                }
                            }
                            else
                            {
                                tempPath.AddArc((GCodeArc)item.path[i], aStart, angleApply, item.path[i].Depth);
                            }                                                                                                   // add point and angle
                        }
                        angleLast = angleNow;
                    }
                    if (tempPath.path.Count > 1)
                    {
                        finalPathList.Add(tempPath);                       // save prev path
                    }
                }
                else
                /* Process Dot */
                {
                    ItemDot dot = new ItemDot(graphicItem.Start.X, graphicItem.Start.Y);
                    dot.Info.CopyData(graphicItem.Info);              // preset global info for GROUP
                    finalPathList.Add(dot);
                    if ((logFlags & loggerSelect) > 0)
                    {
                        Logger.Trace("   Clip Dot copied");
                    }
                }
            }
            completeGraphic.Clear();
            foreach (PathObject item in finalPathList)     // add tile to full graphic
            {
                completeGraphic.Add(item);
            }
        }