public void QueueTravel(IntPoint positionToMoveTo)
        {
            GCodePath path = GetLatestPathWithConfig(travelConfig);

            if (forceRetraction)
            {
                path.Retract    = true;
                forceRetraction = false;
            }

            if (PathFinder != null)
            {
                Polygon pathPolygon = new Polygon();
                if (PathFinder.CreatePathInsideBoundary(LastPosition, positionToMoveTo, pathPolygon))
                {
                    IntPoint lastPathPosition = LastPosition;
                    long     lineLength_um    = 0;

                    // we can stay inside so move within the boundary
                    for (int positionIndex = 0; positionIndex < pathPolygon.Count; positionIndex++)
                    {
                        path.polygon.Add(new IntPoint(pathPolygon[positionIndex], CurrentZ)
                        {
                            Width = 0
                        });
                        lineLength_um   += (pathPolygon[positionIndex] - lastPathPosition).Length();
                        lastPathPosition = pathPolygon[positionIndex];
                    }

                    // If the internal move is very long (> retractionMinimumDistance_um), do a retraction
                    if (lineLength_um > retractionMinimumDistance_um)
                    {
                        path.Retract = true;
                    }
                }
                else
                {
                    if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um))
                    {
                        // We are moving relatively far and are going to cross a boundary so do a retraction.
                        path.Retract = true;
                    }
                }
            }
            else
            {
                if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um))
                {
                    path.Retract = true;
                }
            }

            path.polygon.Add(new IntPoint(positionToMoveTo, CurrentZ)
            {
                Width = 0,
            });
            LastPosition = positionToMoveTo;

            //ValidatePaths();
        }
示例#2
0
        private bool RemoveDoubleDrawPerimeterLines(GCodePath path, double speed)
        {
            return(false);

            if (path.config.lineWidth_um > 0 &&
                path.points.Count > 2 &&                 // If the count is not greater than 2 there is no way it can overlap itself.
                gcodeExport.GetPosition() == path.points[path.points.Count - 1])
            {
                List <List <Point3> > pathsWithOverlapsRemoved = GetPathsWithOverlapsRemoved(path.points, path.config.lineWidth_um / 2);
                if (pathsWithOverlapsRemoved.Count > 0)
                {
                    for (int polygonIndex = 0; polygonIndex < pathsWithOverlapsRemoved.Count; polygonIndex++)
                    {
                        int           startIndex = 0;
                        List <Point3> polygon    = pathsWithOverlapsRemoved[polygonIndex];
                        if (polygonIndex > 0)
                        {
                            gcodeExport.WriteMove(polygon[0], travelConfig.speed, 0);
                            startIndex = 1;                             // We skip the first point in the next extrusion, because we just moved to it.
                        }

                        for (int pointIndex = startIndex; pointIndex < polygon.Count; pointIndex++)
                        {
                            gcodeExport.WriteMove(polygon[pointIndex], speed, path.config.lineWidth_um);
                        }
                    }
                }
            }
        }
示例#3
0
 public GCodePath(GCodePath copyPath)
 {
     this.config        = copyPath.config;
     this.done          = copyPath.done;
     this.extruderIndex = copyPath.extruderIndex;
     this.Retract       = copyPath.Retract;
     this.points        = new Polygon(copyPath.points);
 }
示例#4
0
 public GCodePath(GCodePath copyPath)
 {
     this.config        = copyPath.config;
     this.Done          = copyPath.Done;
     this.ExtruderIndex = copyPath.ExtruderIndex;
     this.Retract       = copyPath.Retract;
     this.Polygon       = new Polygon(copyPath.Polygon);
 }
        public static GCodePath TrimGCodePathEnd(GCodePath inPath, long targetDistance)
        {
            GCodePath path = new GCodePath(inPath);

            // get a new trimmed polygon
            path.Polygon = path.Polygon.TrimEnd(targetDistance);

            return(path);
        }
示例#6
0
        public void QueueTravel(IntPoint positionToMoveTo)
        {
            GCodePath path = GetLatestPathWithConfig(travelConfig);

            if (forceRetraction)
            {
                path.Retract    = true;
                forceRetraction = false;
            }
            else if (outerPerimetersToAvoidCrossing != null)
            {
                Polygon pointList = new Polygon();
                if (outerPerimetersToAvoidCrossing.CreatePathInsideBoundary(LastPosition, positionToMoveTo, pointList))
                {
                    long lineLength_um = 0;
                    // we can stay inside so move within the boundary
                    for (int pointIndex = 0; pointIndex < pointList.Count; pointIndex++)
                    {
                        path.points.Add(new IntPoint(pointList[pointIndex], CurrentZ)
                        {
                            Width = 0
                        });
                        if (pointIndex > 0)
                        {
                            lineLength_um += (pointList[pointIndex] - pointList[pointIndex - 1]).Length();
                        }
                    }

                    // If the internal move is very long (20 mm), do a retraction anyway
                    if (lineLength_um > retractionMinimumDistance_um)
                    {
                        path.Retract = true;
                    }
                }
                else
                {
                    if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um))
                    {
                        // We are moving relatively far and are going to cross a boundary so do a retraction.
                        path.Retract = true;
                    }
                }
            }
            else if (alwaysRetract)
            {
                if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um))
                {
                    path.Retract = true;
                }
            }

            path.points.Add(new IntPoint(positionToMoveTo, CurrentZ)
            {
                Width = 0,
            });
            LastPosition = positionToMoveTo;
        }
示例#7
0
        public void writeTravel(IntPoint positionToMoveTo)
        {
            GCodePath path = getLatestPathWithConfig(travelConfig);

            if (forceRetraction)
            {
                if (!(lastPosition - positionToMoveTo).ShorterThen(retractionMinimumDistance))
                {
                    path.retract = true;
                }
                forceRetraction = false;
            }
            else if (avaidCrossingPerimeters != null)
            {
                List <IntPoint> pointList = new List <IntPoint>();
                if (avaidCrossingPerimeters.CreatePathInsideBoundary(lastPosition, positionToMoveTo, pointList))
                {
                    long lineLength = 0;
                    // we can stay inside so move within the boundary
                    for (int pointIndex = 0; pointIndex < pointList.Count; pointIndex++)
                    {
                        path.points.Add(pointList[pointIndex]);
                        if (pointIndex > 0)
                        {
                            lineLength += (pointList[pointIndex] - pointList[pointIndex - 1]).Length();
                        }
                    }

                    // If the internal move is very long (20 mm), do a retration anyway
                    if (lineLength > (20 * 1000))
                    {
                        path.retract = true;
                    }
                }
                else
                {
                    if (!(lastPosition - positionToMoveTo).ShorterThen(retractionMinimumDistance))
                    {
                        // We are moving relatively far and are going to cross a boundary so do a retraction.
                        path.retract = true;
                    }
                }
            }
            else if (alwaysRetract)
            {
                if (!(lastPosition - positionToMoveTo).ShorterThen(retractionMinimumDistance))
                {
                    path.retract = true;
                }
            }

            path.points.Add(positionToMoveTo);
            lastPosition = positionToMoveTo;
        }
        private GCodePath GetNewPath(GCodePathConfig config)
        {
            GCodePath path = new GCodePath();

            paths.Add(path);
            path.Retract       = RetractType.None;
            path.ExtruderIndex = currentExtruderIndex;
            path.Done          = false;
            path.Config        = config;

            return(path);
        }
示例#9
0
        private static bool TrimPerimeterIfNeeded(GCodePath path, double perimeterStartEndOverlapRatio)
        {
            if (path.config.gcodeComment == "WALL-OUTER" || path.config.gcodeComment == "WALL-INNER")
            {
                long currentDistance = 0;
                long targetDistance  = (long)(path.config.lineWidth_um * (1 - perimeterStartEndOverlapRatio));

                if (path.points.Count > 1)
                {
                    for (int pointIndex = path.points.Count - 1; pointIndex > 0; pointIndex--)
                    {
                        // Calculate distance between 2 points
                        currentDistance = (path.points[pointIndex] - path.points[pointIndex - 1]).Length();

                        // If distance exceeds clip distance:
                        //  - Sets the new last path point
                        if (currentDistance > targetDistance)
                        {
                            long newDistance = currentDistance - targetDistance;
                            if (newDistance > 50)                             // Don't clip segments less than 50 um. We get too much truncation error.
                            {
                                Point3 dir = (path.points[pointIndex] - path.points[pointIndex - 1]) * newDistance / currentDistance;

                                Point3 clippedEndpoint = path.points[pointIndex - 1] + dir;

                                path.points[pointIndex] = clippedEndpoint;
                            }
                            break;
                        }
                        else if (currentDistance == targetDistance)
                        {
                            // Pops off last point because it is at the limit distance
                            path.points.RemoveAt(path.points.Count - 1);
                            break;
                        }
                        else
                        {
                            // Pops last point and reduces distance remaining to target
                            targetDistance -= currentDistance;
                            path.points.RemoveAt(path.points.Count - 1);
                        }
                    }
                }

                // the path was trimmed
                return(true);
            }

            return(false);
        }
示例#10
0
        private bool RemovePerimetersThatOverlap(GCodePath path, double speed, out List <PathAndWidth> pathsWithOverlapsRemoved, bool pathIsClosed)
        {
            pathsWithOverlapsRemoved = null;
            if (path.config.lineWidth_um > 0 &&
                path.points.Count > 2 &&                 // If the count is not greater than 2 there is no way it can overlap itself.
                gcodeExport.GetPosition() == path.points[path.points.Count - 1])
            {
                if (RemovePerimeterOverlaps(path.points, path.config.lineWidth_um, out pathsWithOverlapsRemoved, pathIsClosed) &&
                    pathsWithOverlapsRemoved.Count > 0)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#11
0
        private static void TrimPerimeterIfNeeded(GCodePath path)
        {
            if (path.config.gcodeComment == "WALL-OUTER" || path.config.gcodeComment == "WALL-INNER")
            {
                double currentDistance = 0;
                double targetDistance  = (long)(path.config.lineWidth * .90);

                if (path.points.Count > 1)
                {
                    for (int pointIndex = path.points.Count - 1; pointIndex > 0; pointIndex--)
                    {
                        // Calculate distance between 2 points
                        currentDistance = (path.points[pointIndex] - path.points[pointIndex - 1]).Length();

                        // If distance exceeds clip distance:
                        //  - Sets the new last path point
                        if (currentDistance > targetDistance)
                        {
                            DoublePoint dir = new DoublePoint((path.points[pointIndex].X - path.points[pointIndex - 1].X) / currentDistance, (path.points[pointIndex].Y - path.points[pointIndex - 1].Y) / currentDistance);

                            double newDistance = currentDistance - targetDistance;
                            dir.X *= newDistance;
                            dir.Y *= newDistance;

                            IntPoint clippedEndpoint = path.points[pointIndex - 1] + new IntPoint(dir.X, dir.Y);

                            path.points[pointIndex] = clippedEndpoint;
                            break;
                        }
                        else if (currentDistance == targetDistance)
                        {
                            // Pops off last point because it is at the limit distance
                            path.points.RemoveAt(path.points.Count - 1);
                            break;
                        }
                        else
                        {
                            // Pops last point and reduces distance remaining to target
                            targetDistance = targetDistance - currentDistance;
                            path.points.RemoveAt(path.points.Count - 1);
                        }
                    }
                }
            }
        }
示例#12
0
        public static GCodePath TrimPerimeter(GCodePath inPath, double perimeterStartEndOverlapRatio)
        {
            GCodePath path            = new GCodePath(inPath);
            long      currentDistance = 0;
            long      targetDistance  = (long)(path.config.lineWidth_um * (1 - perimeterStartEndOverlapRatio));

            if (path.points.Count > 1)
            {
                for (int pointIndex = path.points.Count - 1; pointIndex > 0; pointIndex--)
                {
                    // Calculate distance between 2 points
                    currentDistance = (path.points[pointIndex] - path.points[pointIndex - 1]).Length();

                    // If distance exceeds clip distance:
                    //  - Sets the new last path point
                    if (currentDistance > targetDistance)
                    {
                        long newDistance = currentDistance - targetDistance;
                        if (targetDistance > 50)                         // Don't clip segments less than 50 um. We get too much truncation error.
                        {
                            IntPoint dir = (path.points[pointIndex] - path.points[pointIndex - 1]) * newDistance / currentDistance;

                            IntPoint clippedEndpoint = path.points[pointIndex - 1] + dir;

                            path.points[pointIndex] = clippedEndpoint;
                        }
                        break;
                    }
                    else if (currentDistance == targetDistance)
                    {
                        // Pops off last point because it is at the limit distance
                        path.points.RemoveAt(path.points.Count - 1);
                        break;
                    }
                    else
                    {
                        // Pops last point and reduces distance remaining to target
                        targetDistance -= currentDistance;
                        path.points.RemoveAt(path.points.Count - 1);
                    }
                }
            }

            return(path);
        }
示例#13
0
        GCodePath getLatestPathWithConfig(GCodePathConfig config)
        {
            if (paths.Count > 0 &&
                paths[paths.Count - 1].config == config &&
                !paths[paths.Count - 1].done)
            {
                return(paths[paths.Count - 1]);
            }

            paths.Add(new GCodePath());
            GCodePath ret = paths[paths.Count - 1];

            ret.Retract       = false;
            ret.config        = config;
            ret.extruderIndex = currentExtruderIndex;
            ret.done          = false;
            return(ret);
        }
示例#14
0
        private static void TrimPerimeterIfNeeded(GCodePath path)
        {
            if (path.config.gcodeComment == "WALL-OUTER" || path.config.gcodeComment == "WALL-INNER")
            {
                long currentDistance = 0;
                long targetDistance  = (long)(path.config.lineWidth_um * .90);

                if (path.points.Count > 1)
                {
                    for (int pointIndex = path.points.Count - 1; pointIndex > 0; pointIndex--)
                    {
                        // Calculate distance between 2 points
                        currentDistance = (path.points[pointIndex] - path.points[pointIndex - 1]).Length();

                        // If distance exceeds clip distance:
                        //  - Sets the new last path point
                        if (currentDistance > targetDistance)
                        {
                            long newDistance = currentDistance - targetDistance;

                            Point3 dir = path.points[pointIndex] - path.points[pointIndex - 1] * newDistance / currentDistance;

                            Point3 clippedEndpoint = path.points[pointIndex - 1] + dir;

                            path.points[pointIndex] = clippedEndpoint;
                            break;
                        }
                        else if (currentDistance == targetDistance)
                        {
                            // Pops off last point because it is at the limit distance
                            path.points.RemoveAt(path.points.Count - 1);
                            break;
                        }
                        else
                        {
                            // Pops last point and reduces distance remaining to target
                            targetDistance = targetDistance - currentDistance;
                            path.points.RemoveAt(path.points.Count - 1);
                        }
                    }
                }
            }
        }
示例#15
0
        public void CorrectLayerTimeConsideringMinimumLayerTime(double minTime, int minimumPrintingSpeed)
        {
            IntPoint lastPosition = gcodeExport.GetPosition();
            double   travelTime   = 0.0;
            double   extrudeTime  = 0.0;

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                for (int pointIndex = 0; pointIndex < path.Polygon.Count; pointIndex++)
                {
                    IntPoint currentPosition = path.Polygon[pointIndex];
                    double   thisTime        = (lastPosition - currentPosition).LengthMm() / (double)(path.config.speed);
                    if (path.config.lineWidth_um != 0)
                    {
                        extrudeTime += thisTime;
                    }
                    else
                    {
                        travelTime += thisTime;
                    }

                    lastPosition = currentPosition;
                }
            }

            gcodeExport.LayerTime = extrudeTime + travelTime;
            if (gcodeExport.LayerTime < minTime && extrudeTime > 0.0)
            {
                double minExtrudeTime = minTime - travelTime;
                if (minExtrudeTime < 1)
                {
                    minExtrudeTime = 1;
                }

                gcodeExport.LayerSpeedRatio = GetNewLayerSpeedRatio(minimumPrintingSpeed, extrudeTime, minExtrudeTime);
                gcodeExport.LayerTime       = (extrudeTime / gcodeExport.LayerSpeedRatio) + travelTime;
            }

            this.totalPrintTime = gcodeExport.LayerTime;
        }
示例#16
0
        public void writeGCode(bool liftHeadIfNeeded, int layerThickness)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcode.getExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcode.switchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcode.writeRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    gcode.writeComment("TYPE:{0}".FormatWith(path.config.name));
                    lastConfig = path.config;
                }

                int speed = path.config.speed;
                if (path.config.lineWidth != 0)
                {
                    // Only apply the extrudeSpeedFactor to extrusion moves
                    speed = speed * extrudeSpeedFactor / 100;
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.points.Count == 1 &&
                    path.config != travelConfig &&
                    (gcode.getPositionXY() - path.points[0]).ShorterThen(path.config.lineWidth * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    IntPoint nextPosition = path.points[0];
                    int      i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].points.Count == 1 && (nextPosition - paths[i].points[0]).ShorterThen(path.config.lineWidth * 2))
                    {
                        nextPosition = paths[i].points[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcode.getPositionXY();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long     oldLen   = (nextPosition - paths[x].points[0]).vSize();
                            IntPoint newPoint = (paths[x].points[0] + paths[x + 1].points[0]) / 2;
                            long     newLen   = (gcode.getPositionXY() - newPoint).vSize();
                            if (newLen > 0)
                            {
                                gcode.writeMove(newPoint, speed, (int)(path.config.lineWidth * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].points[0];
                        }
                        gcode.writeMove(paths[i - 1].points[0], speed, path.config.lineWidth);
                        pathIndex = i - 1;
                        continue;
                    }
                }

                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }
                if (spiralize)
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    int      z               = gcode.getPositionZ();
                    IntPoint currentPosition = gcode.getPositionXY();
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.points[pointIndex];
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcode.getPositionXY();
                    for (int i = 0; i < path.points.Count; i++)
                    {
                        IntPoint nextPosition = path.points[i];
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        gcode.setZ((int)(z + layerThickness * length / totalLength + .5));
                        gcode.writeMove(path.points[i], speed, path.config.lineWidth);
                    }
                }
                else
                {
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        gcode.writeMove(path.points[pointIndex], speed, path.config.lineWidth);
                    }
                }
            }

            gcode.updateTotalPrintTime();
            if (liftHeadIfNeeded && extraTime > 0.0)
            {
                gcode.writeComment("Small layer, adding delay of {0}".FormatWith(extraTime));
                gcode.writeRetraction();
                gcode.setZ(gcode.getPositionZ() + 3000);
                gcode.writeMove(gcode.getPositionXY(), travelConfig.speed, 0);
                gcode.writeMove(gcode.getPositionXY() - new IntPoint(-20000, 0), travelConfig.speed, 0);
                gcode.writeDelay(extraTime);
            }
        }
示例#17
0
        public void forceMinimumLayerTime(double minTime, int minimumPrintingSpeed)
        {
            IntPoint lastPosition = gcode.getPositionXY();
            double   travelTime   = 0.0;
            double   extrudeTime  = 0.0;

            for (int n = 0; n < paths.Count; n++)
            {
                GCodePath path = paths[n];
                for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                {
                    IntPoint currentPosition = path.points[pointIndex];
                    double   thisTime        = (lastPosition - currentPosition).LengthMm() / (double)(path.config.speed);
                    if (path.config.lineWidth != 0)
                    {
                        extrudeTime += thisTime;
                    }
                    else
                    {
                        travelTime += thisTime;
                    }

                    lastPosition = currentPosition;
                }
            }

            double totalTime = extrudeTime + travelTime;

            if (totalTime < minTime && extrudeTime > 0.0)
            {
                double minExtrudeTime = minTime - travelTime;
                if (minExtrudeTime < 1)
                {
                    minExtrudeTime = 1;
                }

                double factor = extrudeTime / minExtrudeTime;
                for (int n = 0; n < paths.Count; n++)
                {
                    GCodePath path = paths[n];
                    if (path.config.lineWidth == 0)
                    {
                        continue;
                    }

                    int speed = (int)(path.config.speed * factor);
                    if (speed < minimumPrintingSpeed)
                    {
                        factor = (double)(minimumPrintingSpeed) / (double)(path.config.speed);
                    }
                }

                //Only slow down with the minimum time if that will be slower then a factor already set. First layer slowdown also sets the speed factor.
                if (factor * 100 < getExtrudeSpeedFactor())
                {
                    setExtrudeSpeedFactor((int)(factor * 100));
                }
                else
                {
                    factor = getExtrudeSpeedFactor() / 100.0;
                }

                if (minTime - (extrudeTime / factor) - travelTime > 0.1)
                {
                    //TODO: Use up this extra time (circle around the print?)
                    this.extraTime = minTime - (extrudeTime / factor) - travelTime;
                }
                this.totalPrintTime = (extrudeTime / factor) + travelTime;
            }
            else
            {
                this.totalPrintTime = totalTime;
            }
        }
示例#18
0
        public void WriteGCode(bool liftHeadIfNeeded, int layerThickness)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcode.GetExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcode.SwitchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcode.WriteRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    //gcode.WriteComment("TYPE:{0}".FormatWith(path.config.gcodeComment));
                    lastConfig = path.config;

                    ////后加的//只是边框,不填充。
                    if ((path.config.gcodeComment == "SKIRT") || (path.config.gcodeComment == "FILL") || (path.config.gcodeComment == "TOP-FILL"))
                    {
                        return;
                    }
                }

                double speed = path.config.speed;
                if (path.config.lineWidth != 0)
                {
                    // Only apply the extrudeSpeedFactor to extrusion moves
                    speed = speed * extrudeSpeedFactor / 100;
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.points.Count == 1 &&
                    path.config != travelConfig &&
                    (gcode.GetPositionXY() - path.points[0]).ShorterThen(path.config.lineWidth * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    IntPoint nextPosition = path.points[0];
                    int      i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].points.Count == 1 && (nextPosition - paths[i].points[0]).ShorterThen(path.config.lineWidth * 2))
                    {
                        nextPosition = paths[i].points[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcode.GetPositionXY();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long     oldLen   = (nextPosition - paths[x].points[0]).Length();
                            IntPoint newPoint = (paths[x].points[0] + paths[x + 1].points[0]) / 2;
                            long     newLen   = (gcode.GetPositionXY() - newPoint).Length();
                            if (newLen > 0)
                            {
                                gcode.WriteMove(newPoint, speed, (int)(path.config.lineWidth * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].points[0];
                        }

                        gcode.WriteMove(paths[i - 1].points[0], speed, path.config.lineWidth);
                        pathIndex = i - 1;
                        continue;
                    }
                }

                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }
                if (spiralize)
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    int      z               = gcode.GetPositionZ();
                    IntPoint currentPosition = gcode.GetPositionXY();
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.points[pointIndex];
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcode.GetPositionXY();
                    for (int i = 0; i < path.points.Count; i++)
                    {
                        IntPoint nextPosition = path.points[i];
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        gcode.setZ((int)(z + layerThickness * length / totalLength + .5));
                        gcode.WriteMove(path.points[i], speed, path.config.lineWidth);
                    }
                }
                else
                {
#if false
                    // This is test code to remove double drawn small perimeter lines.
                    if (path.config.lineWidth > 0 &&
                        path.points.Count > 2 &&                         // If the count is not greater than 2 there is no way it can ovelap itself.
                        gcode.GetPositionXY() == path.points[path.points.Count - 1])
                    {
                        Polygons pathsWithOverlapsRemoved = GetPathsWithOverlapsRemoved(path.points, path.config.lineWidth / 2);
                        if (pathsWithOverlapsRemoved.Count > 0)
                        {
                            for (int polygonIndex = 0; polygonIndex < pathsWithOverlapsRemoved.Count; polygonIndex++)
                            {
                                int     startIndex = 0;
                                Polygon polygon    = pathsWithOverlapsRemoved[polygonIndex];
                                if (polygonIndex > 0)
                                {
                                    gcode.WriteMove(polygon[0], travelConfig.speed, 0);
                                    startIndex = 1;                                     // We skip the first point in the next extrusion, because we just moved to it.
                                }

                                for (int pointIndex = startIndex; pointIndex < polygon.Count; pointIndex++)
                                {
                                    gcode.WriteMove(polygon[pointIndex], speed, path.config.lineWidth);
                                }
                            }
                        }
                    }
                    else
#endif
                    {
                        //TrimPerimeterIfNeeded(path);

                        for (int i = 0; i < path.points.Count; i++)
                        {
                            gcode.WriteMove(path.points[i], speed, path.config.lineWidth);
                        }
                    }
                }
            }

            gcode.UpdateTotalPrintTime();
            if (liftHeadIfNeeded && extraTime > 0.0)
            {
                gcode.WriteComment("Small layer, adding delay of {0}".FormatWith(extraTime));
                gcode.WriteRetraction();
                gcode.setZ(gcode.GetPositionZ() + 3000);
                gcode.WriteMove(gcode.GetPositionXY(), travelConfig.speed, 0);
                gcode.WriteMove(gcode.GetPositionXY() - new IntPoint(-20000, 0), travelConfig.speed, 0);
                gcode.WriteDelay(extraTime);
            }
        }
示例#19
0
        public void WriteQueuedGCode(int layerThickness)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcodeExport.GetExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcodeExport.SwitchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcodeExport.WriteRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    gcodeExport.WriteComment("TYPE:{0}".FormatWith(path.config.gcodeComment));
                    lastConfig = path.config;
                }

                double speed = path.config.speed;
                if (path.config.lineWidth_um != 0)
                {
                    // Only apply the extrudeSpeedFactor to extrusion moves
                    speed = speed * extrudeSpeedFactor / 100;
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.points.Count == 1 &&
                    path.config != travelConfig &&
                    (gcodeExport.GetPositionXY() - path.points[0].XYPoint).ShorterThen(path.config.lineWidth_um * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    Point3 nextPosition = path.points[0];
                    int    i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].points.Count == 1 && (nextPosition - paths[i].points[0]).ShorterThen(path.config.lineWidth_um * 2))
                    {
                        nextPosition = paths[i].points[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcodeExport.GetPosition();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long   oldLen   = (nextPosition - paths[x].points[0]).Length();
                            Point3 newPoint = (paths[x].points[0] + paths[x + 1].points[0]) / 2;
                            long   newLen   = (gcodeExport.GetPosition() - newPoint).Length();
                            if (newLen > 0)
                            {
                                gcodeExport.WriteMove(newPoint, speed, (int)(path.config.lineWidth_um * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].points[0];
                        }

                        gcodeExport.WriteMove(paths[i - 1].points[0], speed, path.config.lineWidth_um);
                        pathIndex = i - 1;
                        continue;
                    }
                }


                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }

                if (spiralize)                 // if we are still in spiralize mode
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    long     z               = gcodeExport.GetPositionZ();
                    IntPoint currentPosition = gcodeExport.GetPositionXY();
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.points[pointIndex].XYPoint;
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcodeExport.GetPositionXY();
                    for (int i = 0; i < path.points.Count; i++)
                    {
                        IntPoint nextPosition = path.points[i].XYPoint;
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        Point3 nextExtrusion = path.points[i];
                        nextExtrusion.z = (int)(z + layerThickness * length / totalLength + .5);
                        gcodeExport.WriteMove(nextExtrusion, speed, path.config.lineWidth_um);
                    }
                }
                else
                {
                    // This is test code to remove double drawn small perimeter lines.
                    if (RemoveDoubleDrawPerimeterLines(path, speed))
                    {
                        return;
                    }
                    else
                    {
                        //TrimPerimeterIfNeeded(path);

                        for (int i = 0; i < path.points.Count; i++)
                        {
                            gcodeExport.WriteMove(path.points[i], speed, path.config.lineWidth_um);
                        }
                    }
                }
            }

            gcodeExport.UpdateTotalPrintTime();
        }
示例#20
0
        public void WriteQueuedGCode(int layerThickness, int fanSpeedPercent = -1, int bridgeFanSpeedPercent = -1)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcodeExport.GetExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcodeExport.SwitchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcodeExport.WriteRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    if (path.config.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(bridgeFanSpeedPercent);
                    }
                    else if (lastConfig?.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(fanSpeedPercent);
                    }

                    gcodeExport.WriteComment("TYPE:{0}".FormatWith(path.config.gcodeComment));
                    lastConfig = path.config;
                }

                double speed = path.config.speed;

                if (path.config.lineWidth_um != 0)
                {
                    // Prevent cooling overrides from affecting bridge moves
                    if (path.config.gcodeComment != "BRIDGE")
                    {
                        speed = speed * extrudeSpeedFactor / 100;
                    }
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.points.Count == 1 &&
                    path.config != travelConfig &&
                    (gcodeExport.GetPositionXY() - path.points[0].XYPoint).ShorterThen(path.config.lineWidth_um * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    Point3 nextPosition = path.points[0];
                    int    i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].points.Count == 1 && (nextPosition - paths[i].points[0]).ShorterThen(path.config.lineWidth_um * 2))
                    {
                        nextPosition = paths[i].points[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcodeExport.GetPosition();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long   oldLen   = (nextPosition - paths[x].points[0]).Length();
                            Point3 newPoint = (paths[x].points[0] + paths[x + 1].points[0]) / 2;
                            long   newLen   = (gcodeExport.GetPosition() - newPoint).Length();
                            if (newLen > 0)
                            {
                                gcodeExport.WriteMove(newPoint, speed, (int)(path.config.lineWidth_um * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].points[0];
                        }

                        gcodeExport.WriteMove(paths[i - 1].points[0], speed, path.config.lineWidth_um);
                        pathIndex = i - 1;
                        continue;
                    }
                }


                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }

                if (spiralize)                 // if we are still in spiralize mode
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    long     z               = gcodeExport.GetPositionZ();
                    IntPoint currentPosition = gcodeExport.GetPositionXY();
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.points[pointIndex].XYPoint;
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcodeExport.GetPositionXY();
                    for (int i = 0; i < path.points.Count; i++)
                    {
                        IntPoint nextPosition = path.points[i].XYPoint;
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        Point3 nextExtrusion = path.points[i];
                        nextExtrusion.z = (int)(z + layerThickness * length / totalLength + .5);
                        gcodeExport.WriteMove(nextExtrusion, speed, path.config.lineWidth_um);
                    }
                }
                else
                {
                    bool pathIsClosed = true;
                    if (perimeterStartEndOverlapRatio < 1)
                    {
                        pathIsClosed = !TrimPerimeterIfNeeded(path, perimeterStartEndOverlapRatio);
                    }

                    // This is test code to remove double drawn small perimeter lines.
                    List <PathAndWidth> pathsWithOverlapsRemoved;
                    if (RemovePerimetersThatOverlap(path, speed, out pathsWithOverlapsRemoved, pathIsClosed))
                    {
                        for (int polygonIndex = 0; polygonIndex < pathsWithOverlapsRemoved.Count; polygonIndex++)
                        {
                            PathAndWidth polygon = pathsWithOverlapsRemoved[polygonIndex];

                            if (polygon.Path.Count == 2)
                            {
                                // make sure the path is ordered with the first point the closest to where we are now
                                Point3 currentPosition = gcodeExport.GetPosition();
                                // if the second point is closer swap them
                                if ((polygon.Path[1] - currentPosition).LengthSquared() < (polygon.Path[0] - currentPosition).LengthSquared())
                                {
                                    // swap them
                                    Point3 temp = polygon.Path[0];
                                    polygon.Path[0] = polygon.Path[1];
                                    polygon.Path[1] = temp;
                                }
                            }

                            // move to the start of this polygon
                            gcodeExport.WriteMove(polygon.Path[0], travelConfig.speed, 0);

                            // write all the data for the polygon
                            for (int pointIndex = 1; pointIndex < polygon.Path.Count; pointIndex++)
                            {
                                gcodeExport.WriteMove(polygon.Path[pointIndex], speed, polygon.ExtrusionWidthUm);
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < path.points.Count; i++)
                        {
                            gcodeExport.WriteMove(path.points[i], speed, path.config.lineWidth_um);
                        }
                    }
                }
            }

            gcodeExport.UpdateTotalPrintTime();
        }
示例#21
0
        public void QueueTravel(IntPoint positionToMoveTo, bool forceUniquePath = false)
        {
            GCodePath path = GetLatestPathWithConfig(travelConfig, forceUniquePath || !canAppendTravel);

            canAppendTravel = !forceUniquePath;

            if (forceRetraction)
            {
                path.Retract    = RetractType.Force;
                forceRetraction = false;
            }

            if (PathFinder != null)
            {
                Polygon pathPolygon = new Polygon();
                if (PathFinder.CreatePathInsideBoundary(LastPosition, positionToMoveTo, pathPolygon, true, gcodeExport.LayerIndex))
                {
                    IntPoint lastPathPosition = LastPosition;
                    long     lineLength_um    = 0;

                    if (pathPolygon.Count > 0)
                    {
                        // we can stay inside so move within the boundary
                        for (int positionIndex = 0; positionIndex < pathPolygon.Count; positionIndex++)
                        {
                            path.Polygon.Add(new IntPoint(pathPolygon[positionIndex], CurrentZ)
                            {
                                Width = 0
                            });
                            lineLength_um   += (pathPolygon[positionIndex] - lastPathPosition).Length();
                            lastPathPosition = pathPolygon[positionIndex];
                        }

                        // If the internal move is very long (> retractionMinimumDistance_um), do a retraction
                        if (lineLength_um > retractionMinimumDistance_um)
                        {
                            path.Retract = RetractType.Requested;
                        }
                    }
                    // else the path is good it just goes directly to the positionToMoveTo
                }
                else if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um / 10))
                {
                    // can't find a good path and moving more than a very little bit
                    path.Retract = RetractType.Requested;
                }
            }

            // Always check if the distance is greater than the amount need to retract.
            if ((LastPosition - positionToMoveTo).LongerThen(retractionMinimumDistance_um))
            {
                path.Retract = RetractType.Requested;
            }

            path.Polygon.Add(new IntPoint(positionToMoveTo, CurrentZ)
            {
                Width = 0,
            });

            LastPosition = positionToMoveTo;

            //ValidatePaths();
        }
示例#22
0
 bool PathCanAdjustSpeed(GCodePath path)
 {
     return(path.Config.LineWidthUM > 0 && path.Config.GCodeComment != "BRIDGE");
 }
示例#23
0
        public void WriteQueuedGCode(int layerThickness, int fanSpeedPercent = -1, int bridgeFanSpeedPercent = -1)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcodeExport.GetExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcodeExport.SwitchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcodeExport.WriteRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    if (path.config.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(bridgeFanSpeedPercent);
                    }
                    else if (lastConfig?.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(fanSpeedPercent);
                    }

                    gcodeExport.WriteComment("TYPE:{0}".FormatWith(path.config.gcodeComment));
                    lastConfig = path.config;
                }

                double speed = path.config.speed;

                if (path.config.lineWidth_um != 0)
                {
                    // Prevent cooling overrides from affecting bridge moves
                    if (path.config.gcodeComment != "BRIDGE")
                    {
                        speed = speed * extrudeSpeedFactor / 100;
                    }
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.points.Count == 1 &&
                    path.config != travelConfig &&
                    (gcodeExport.GetPositionXY() - path.points[0]).ShorterThen(path.config.lineWidth_um * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    IntPoint nextPosition = path.points[0];
                    int      i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].points.Count == 1 && (nextPosition - paths[i].points[0]).ShorterThen(path.config.lineWidth_um * 2))
                    {
                        nextPosition = paths[i].points[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcodeExport.GetPosition();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long     oldLen   = (nextPosition - paths[x].points[0]).Length();
                            IntPoint newPoint = (paths[x].points[0] + paths[x + 1].points[0]) / 2;
                            long     newLen   = (gcodeExport.GetPosition() - newPoint).Length();
                            if (newLen > 0)
                            {
                                gcodeExport.WriteMove(newPoint, speed, (int)(path.config.lineWidth_um * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].points[0];
                        }

                        long lineWidth_um = path.config.lineWidth_um;
                        if (paths[i - 1].points[0].Width != 0)
                        {
                            lineWidth_um = paths[i - 1].points[0].Width;
                        }

                        gcodeExport.WriteMove(paths[i - 1].points[0], speed, lineWidth_um);
                        pathIndex = i - 1;
                        continue;
                    }
                }


                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }

                if (spiralize)                 // if we are still in spiralize mode
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    long     z               = gcodeExport.GetPositionZ();
                    IntPoint currentPosition = gcodeExport.GetPositionXY();
                    for (int pointIndex = 0; pointIndex < path.points.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.points[pointIndex];
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcodeExport.GetPositionXY();
                    for (int i = 0; i < path.points.Count; i++)
                    {
                        IntPoint nextPosition = path.points[i];
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        IntPoint nextExtrusion = path.points[i];
                        nextExtrusion.Z = (int)(z + layerThickness * length / totalLength + .5);
                        gcodeExport.WriteMove(nextExtrusion, speed, path.config.lineWidth_um);
                    }
                }
                else
                {
                    // This is test code to remove double drawn small perimeter lines.
                    Polygons pathsWithOverlapsRemoved = null;
                    bool     pathHadOverlaps          = false;
                    bool     pathIsClosed             = true;
                    if (mergeOverlappingLines &&
                        (path.config.gcodeComment == "WALL-OUTER" || path.config.gcodeComment == "WALL-INNER"))
                    {
                        //string perimeterString = Newtonsoft.Json.JsonConvert.SerializeObject(path);
                        if (perimeterStartEndOverlapRatio < 1)
                        {
                            path = TrimPerimeter(path, perimeterStartEndOverlapRatio);
                            //string trimmedString = Newtonsoft.Json.JsonConvert.SerializeObject(path);
                            // it was closed but now it isn't
                            pathIsClosed = false;
                        }

                        if (path.config.lineWidth_um > 0 &&
                            path.points.Count > 2)
                        {
                            // have to add in the position we are currently at
                            path.points.Insert(0, gcodeExport.GetPosition());
                            //string openPerimeterString = Newtonsoft.Json.JsonConvert.SerializeObject(path);
                            pathHadOverlaps = MergePerimeterOverlaps(path.points, path.config.lineWidth_um, out pathsWithOverlapsRemoved, pathIsClosed) &&
                                              pathsWithOverlapsRemoved.Count > 0;
                            //string trimmedString = Newtonsoft.Json.JsonConvert.SerializeObject(pathsWithOverlapsRemoved);
                        }
                    }

                    if (pathHadOverlaps)
                    {
                        for (int polygonIndex = 0; polygonIndex < pathsWithOverlapsRemoved.Count; polygonIndex++)
                        {
                            Polygon polygon = pathsWithOverlapsRemoved[polygonIndex];

                            if (polygon.Count == 2)
                            {
                                // make sure the path is ordered with the first point the closest to where we are now
                                IntPoint currentPosition = gcodeExport.GetPosition();
                                // if the second point is closer swap them
                                if ((polygon[1] - currentPosition).LengthSquared() < (polygon[0] - currentPosition).LengthSquared())
                                {
                                    // swap them
                                    IntPoint temp = polygon[0];
                                    polygon[0] = polygon[1];
                                    polygon[1] = temp;
                                }
                            }

                            // move to the start of this polygon
                            gcodeExport.WriteMove(polygon[0], travelConfig.speed, 0);

                            // write all the data for the polygon
                            for (int pointIndex = 1; pointIndex < polygon.Count; pointIndex++)
                            {
                                gcodeExport.WriteMove(polygon[pointIndex], speed, polygon[pointIndex - 1].Width);
                            }
                        }
                    }
                    else
                    {
                        int outputCount = path.points.Count;
                        for (int i = 0; i < outputCount; i++)
                        {
                            long lineWidth_um = path.config.lineWidth_um;
                            if (path.points[i].Width != 0)
                            {
                                lineWidth_um = path.points[i].Width;
                            }

                            gcodeExport.WriteMove(path.points[i], speed, lineWidth_um);
                        }
                    }
                }
            }

            gcodeExport.UpdateTotalPrintTime();
        }
 bool PathCanAdjustSpeed(GCodePath path)
 {
     return(path.Config.lineWidth_um > 0 && path.Config.gcodeComment != "BRIDGE");
 }
示例#25
0
        public void WriteQueuedGCode(int layerThickness, int fanSpeedPercent = -1, int bridgeFanSpeedPercent = -1)
        {
            GCodePathConfig lastConfig    = null;
            int             extruderIndex = gcodeExport.GetExtruderIndex();

            for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++)
            {
                GCodePath path = paths[pathIndex];
                if (extruderIndex != path.extruderIndex)
                {
                    extruderIndex = path.extruderIndex;
                    gcodeExport.SwitchExtruder(extruderIndex);
                }
                else if (path.Retract)
                {
                    gcodeExport.WriteRetraction();
                }
                if (path.config != travelConfig && lastConfig != path.config)
                {
                    if (path.config.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(bridgeFanSpeedPercent);
                    }
                    else if (lastConfig?.gcodeComment == "BRIDGE" && bridgeFanSpeedPercent != -1)
                    {
                        gcodeExport.WriteFanCommand(fanSpeedPercent);
                    }

                    gcodeExport.WriteComment("TYPE:{0}".FormatWith(path.config.gcodeComment));
                    lastConfig = path.config;
                }

                double speed = path.config.speed;

                if (path.config.lineWidth_um != 0)
                {
                    // Prevent cooling overrides from affecting bridge moves
                    if (path.config.gcodeComment != "BRIDGE")
                    {
                        speed = speed * extrudeSpeedFactor / 100;
                    }
                }
                else
                {
                    speed = speed * travelSpeedFactor / 100;
                }

                if (path.polygon.Count == 1 &&
                    path.config != travelConfig &&
                    (gcodeExport.GetPositionXY() - path.polygon[0]).ShorterThen(path.config.lineWidth_um * 2))
                {
                    //Check for lots of small moves and combine them into one large line
                    IntPoint nextPosition = path.polygon[0];
                    int      i            = pathIndex + 1;
                    while (i < paths.Count && paths[i].polygon.Count == 1 && (nextPosition - paths[i].polygon[0]).ShorterThen(path.config.lineWidth_um * 2))
                    {
                        nextPosition = paths[i].polygon[0];
                        i++;
                    }
                    if (paths[i - 1].config == travelConfig)
                    {
                        i--;
                    }

                    if (i > pathIndex + 2)
                    {
                        nextPosition = gcodeExport.GetPosition();
                        for (int x = pathIndex; x < i - 1; x += 2)
                        {
                            long     oldLen   = (nextPosition - paths[x].polygon[0]).Length();
                            IntPoint newPoint = (paths[x].polygon[0] + paths[x + 1].polygon[0]) / 2;
                            long     newLen   = (gcodeExport.GetPosition() - newPoint).Length();
                            if (newLen > 0)
                            {
                                gcodeExport.WriteMove(newPoint, speed, (int)(path.config.lineWidth_um * oldLen / newLen));
                            }

                            nextPosition = paths[x + 1].polygon[0];
                        }

                        long lineWidth_um = path.config.lineWidth_um;
                        if (paths[i - 1].polygon[0].Width != 0)
                        {
                            lineWidth_um = paths[i - 1].polygon[0].Width;
                        }

                        gcodeExport.WriteMove(paths[i - 1].polygon[0], speed, lineWidth_um);
                        pathIndex = i - 1;
                        continue;
                    }
                }

                bool spiralize = path.config.spiralize;
                if (spiralize)
                {
                    //Check if we are the last spiralize path in the list, if not, do not spiralize.
                    for (int m = pathIndex + 1; m < paths.Count; m++)
                    {
                        if (paths[m].config.spiralize)
                        {
                            spiralize = false;
                        }
                    }
                }

                if (spiralize)                 // if we are still in spiralize mode
                {
                    //If we need to spiralize then raise the head slowly by 1 layer as this path progresses.
                    double   totalLength     = 0;
                    long     z               = gcodeExport.GetPositionZ();
                    IntPoint currentPosition = gcodeExport.GetPositionXY();
                    for (int pointIndex = 0; pointIndex < path.polygon.Count; pointIndex++)
                    {
                        IntPoint nextPosition = path.polygon[pointIndex];
                        totalLength    += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                    }

                    double length = 0.0;
                    currentPosition = gcodeExport.GetPositionXY();
                    for (int i = 0; i < path.polygon.Count; i++)
                    {
                        IntPoint nextPosition = path.polygon[i];
                        length         += (currentPosition - nextPosition).LengthMm();
                        currentPosition = nextPosition;
                        IntPoint nextExtrusion = path.polygon[i];
                        nextExtrusion.Z = (int)(z + layerThickness * length / totalLength + .5);
                        gcodeExport.WriteMove(nextExtrusion, speed, path.config.lineWidth_um);
                    }
                }
                else
                {
                    // This is test code to remove double drawn small perimeter lines.
                    if (path.config.gcodeComment == "WALL-OUTER" || path.config.gcodeComment == "WALL-INNER")
                    {
                        //string perimeterString = Newtonsoft.Json.JsonConvert.SerializeObject(path);
                        if (perimeterStartEndOverlapRatio < 1)
                        {
                            path = TrimPerimeter(path, perimeterStartEndOverlapRatio);
                        }
                    }

                    int outputCount = path.polygon.Count;
                    for (int i = 0; i < outputCount; i++)
                    {
                        long lineWidth_um = path.config.lineWidth_um;
                        if (path.polygon[i].Width != 0)
                        {
                            lineWidth_um = path.polygon[i].Width;
                        }

                        gcodeExport.WriteMove(path.polygon[i], speed, lineWidth_um);
                    }
                }
            }

            gcodeExport.UpdateTotalPrintTime();
        }