예제 #1
0
        public virtual void LinearMoveToAbsolute3d(LinearMoveData move)
        {
            if (ActivePath == null)
            {
                throw new Exception("GCodeToLayerPaths.LinearMoveToAbsolute3D: ActivePath is null!");
            }

            // if we are doing a Z-move, convert to 3D path
            bool bZMove = (ActivePath.VertexCount > 0 && ActivePath.End.Position.z != move.position.z);

            if (bZMove)
            {
                ActivePath.ChangeType(ToolpathTypes.PlaneChange);
            }

            PrintVertex vtx = new PrintVertex(
                move.position, move.rate, PathDimensions, move.extrude.x);

            if (move.source != null)
            {
                vtx.Source = move.source;
            }

            ActivePath.AppendVertex(vtx, TPVertexFlags.None);
        }
예제 #2
0
        } // Calculate()

        /// <summary>
        /// Scale the extrusion speeds by the given scale factor
        /// </summary>
        public void ScaleExtrudeTimes(double scaleFactor)
        {
            // filter paths
            foreach (IToolpath ipath in Paths)
            {
                ToolpathUtil.ApplyToLeafPaths(ipath, (p) => {
                    if (p is LinearToolpath3 <PrintVertex> )
                    {
                        LinearToolpath3 <PrintVertex> path = p as LinearToolpath3 <PrintVertex>;
                        if (path != null && path.Type == ToolpathTypes.Deposition)
                        {
                            for (int i = 0; i < path.VertexCount; ++i)
                            {
                                PrintVertex v     = path[i];
                                double rate       = path[i].FeedRate;
                                double scaledRate = v.FeedRate * scaleFactor;
                                if (scaledRate < Settings.MinExtrudeSpeed)
                                {
                                    scaledRate = Settings.MinExtrudeSpeed;
                                }
                                v.FeedRate = scaledRate;
                                path.UpdateVertex(i, v);
                            }
                        }
                    }
                });
            }
        }
예제 #3
0
 public PrintVertex(PrintVertex other)
 {
     Position     = new Vector3d(other.Position);
     FeedRate     = other.FeedRate;
     Dimensions   = new Vector2d(other.Dimensions);
     Extrusion    = new Vector3d(other.Extrusion);
     ExtendedData = other.ExtendedData == null ? null : new TPVertexData(other.ExtendedData);
     Source       = other.Source;
 }
예제 #4
0
        public virtual void BeginCut()
        {
            var newPath = new LinearToolpath();

            newPath.Type = ToolpathTypes.Cut;
            if (ActivePath != null && ActivePath.VertexCount > 0)
            {
                PrintVertex curp = new PrintVertex(ActivePath.End.Position, GCodeUtil.UnspecifiedValue, PathDimensions, GCodeUtil.UnspecifiedValue);
                newPath.AppendVertex(curp, TPVertexFlags.IsPathStart);
            }

            push_active_path();
            ActivePath = newPath;
        }
예제 #5
0
        public virtual void Process(PrintLayerData layerData, ToolpathSet layerPaths)
        {
            if (layerData.PreviousLayer == null)
            {
                return;
            }
            if (layerData.PreviousLayer.SupportAreas == null || layerData.PreviousLayer.SupportAreas.Count == 0)
            {
                return;
            }

            LayerCache cache = build_cache(layerData.PreviousLayer);

            Func <Vector3d, Vector3d> ZOffsetF = (v) =>
            {
                return(new Vector3d(v.x, v.y, v.z + ZOffsetMM));
            };

            foreach (var toolpath in layerPaths)
            {
                LinearToolpath tp = toolpath as LinearToolpath;
                if (tp == null)
                {
                    continue;
                }
                if (!tp.FillType.IsPart())
                {
                    continue;
                }

                int N = tp.VertexCount;
                //for ( int i = 0; i < N; ++i ) {
                for (int i = 1; i < N - 1; ++i)
                {       // start and end cannot be modified!
                    PrintVertex v = tp[i];
                    if (is_over_support(v.Position.xy, ref cache))
                    {
                        v.Position = ZOffsetF(v.Position);
                        tp.UpdateVertex(i, v);
                    }
                }
            }
        }
예제 #6
0
        public virtual void ProcessGCodeLine(GCodeLine line)
        {
            if (line == null || line.type == GCodeLine.LType.Blank)
            {
                return;
            }

            pointCount++;

            if (line.comment != null && line.comment.Contains("layer") && !line.comment.Contains("feature"))
            {
                if (toolpath != null)
                {
                    Emit(toolpath, layerIndex, pointCount - toolpath.Count);
                    toolpath = null;
                }
                layerIndex++;

                return;
            }

            ExtractPositionFeedrateAndExtrusion(line, ref position, ref feedrate, ref extrusion);
            ExtractDimensions(line, ref dimensions);
            GCodeLineUtil.ExtractFillType(line, ref fillType);

            if (line.comment?.Contains("Plane Change") ?? false)
            {
                OnNewPlane(position.z, layerIndex);
            }

            PrintVertex vertex = new PrintVertex(position, feedrate, dimensions)
            {
                Extrusion = new Vector3d(extrusion, 0, 0),
                Source    = fillType,
            };

            if (line.type == GCodeLine.LType.GCode)
            {
                if (toolpath == null)
                {
                    if (extrusion > lastVertex.Extrusion.x)
                    {
                        lastVertex.Source       = fillType;
                        lastVertex.Dimensions   = vertex.Dimensions;
                        lastVertex.FeedRate     = vertex.FeedRate;
                        lastVertex.ExtendedData = vertex.ExtendedData;

                        toolpath = new List <PrintVertex> {
                            lastVertex, vertex
                        };
                    }
                    else
                    {
                        RaiseLineGenerated(new List <Vector3d>()
                        {
                            lastVertex.Position, vertex.Position
                        }, layerIndex);
                    }
                }
                else
                {
                    toolpath.Add(vertex);
                    if (extrusion <= lastVertex.Extrusion.x)
                    {
                        Emit(toolpath, layerIndex, pointCount - toolpath.Count);
                        toolpath = null;
                    }
                }
            }

            lastVertex = vertex;
        }
예제 #7
0
 public void BeginGCodeLineStream()
 {
     lastVertex = new PrintVertex(Vector3d.Zero, 0, Vector2d.Zero);
     layerIndex = 0;
 }
예제 #8
0
        public void Calculate(Vector3d vStartPos, double fStartA, bool alreadyInRetract = false)
        {
            double   curA    = fStartA;
            Vector3d curPos  = vStartPos;
            double   curRate = 0;

            bool inRetract = alreadyInRetract;

            // filter paths
            List <IToolpath> allPaths = new List <IToolpath>();

            foreach (IToolpath ipath in Paths)
            {
                ToolpathUtil.ApplyToLeafPaths(ipath, (p) => {
                    if (p is LinearToolpath3 <PrintVertex> || p is ResetExtruderPathHack)
                    {
                        allPaths.Add(p);
                    }
                });
            }
            int N = allPaths.Count;


            LinearToolpath3 <PrintVertex> prev_path = null;

            for (int pi = 0; pi < N; ++pi)
            {
                if (allPaths[pi] is ResetExtruderPathHack)
                {
                    curA = 0;
                    continue;
                }
                LinearToolpath3 <PrintVertex> path = allPaths[pi] as LinearToolpath3 <PrintVertex>;

                if (path == null)
                {
                    throw new Exception("Invalid path type!");
                }
                if (!(path.Type == ToolpathTypes.Deposition || path.Type == ToolpathTypes.PlaneChange || path.Type == ToolpathTypes.Travel))
                {
                    throw new Exception("Unknown path type!");
                }

                // if we are travelling between two extrusion paths, and neither is support,
                // and the travel distance is very short,then we will skip the retract.
                // [TODO] should only do this on interior travels. We should determine that upstream and set a flag on travel path.
                bool skip_retract = false;
                if (path.Type == ToolpathTypes.Travel && path.Length < MinRetractTravelLength)
                {
                    bool prev_is_model_deposition =
                        (prev_path != null) && (prev_path.Type == ToolpathTypes.Deposition) && ((prev_path.TypeModifiers & FillTypeFlags.SupportMaterial) == 0);
                    LinearToolpath3 <PrintVertex> next_path = (pi < N - 1) ? (allPaths[pi + 1] as LinearToolpath3 <PrintVertex>) : null;
                    bool next_is_model_deposition           =
                        (next_path != null) && (next_path.Type == ToolpathTypes.Deposition) && ((next_path.TypeModifiers & FillTypeFlags.SupportMaterial) == 0);
                    skip_retract = prev_is_model_deposition && next_is_model_deposition;
                }
                if (EnableRetraction == false)
                {
                    skip_retract = true;
                }

                // figure out volume scaling based on path type
                double vol_scale = 1.0;
                if ((path.TypeModifiers & FillTypeFlags.SupportMaterial) != 0)
                {
                    vol_scale *= SupportExtrudeScale;
                }
                else if ((path.TypeModifiers & FillTypeFlags.BridgeSupport) != 0)
                {
                    vol_scale *= Settings.BridgeVolumeScale;
                }

                for (int i = 0; i < path.VertexCount; ++i)
                {
                    bool last_vtx = (i == path.VertexCount - 1);

                    Vector3d newPos  = path[i].Position;
                    double   newRate = path[i].FeedRate;

                    // default line thickness and height
                    double path_width  = Settings.Machine.NozzleDiamMM;
                    double path_height = Settings.LayerHeightMM;

                    // override with custom dimensions if provided
                    Vector2d vtx_dims = path[i].Dimensions;
                    if (vtx_dims.x > 0 && vtx_dims.x < 1000.0)
                    {
                        path_width = vtx_dims.x;
                    }
                    if (vtx_dims.y > 0 && vtx_dims.y < 1000.0)
                    {
                        path_height = vtx_dims.y;
                    }

                    if (path.Type != ToolpathTypes.Deposition)
                    {
                        // [RMS] if we switched to a travel move we retract, unless we don't
                        if (skip_retract == false)
                        {
                            if (!inRetract)
                            {
                                curA     -= FixedRetractDistance;
                                inRetract = true;
                            }
                        }

                        curPos  = newPos;
                        curRate = newRate;
                    }
                    else
                    {
                        // for i == 0 this dist is always 0 !!
                        double dist = (newPos - curPos).Length;

                        if (i == 0)
                        {
                            Util.gDevAssert(dist == 0);     // next path starts at end of previous!!
                            if (inRetract)
                            {
                                curA     += FixedRetractDistance;
                                inRetract = false;
                            }
                        }
                        else
                        {
                            curPos  = newPos;
                            curRate = newRate;

                            double feed = ExtrusionMath.PathLengthToFilamentLength(
                                path_height, path_width, Settings.Machine.FilamentDiamMM,
                                dist, vol_scale);
                            curA += feed;
                        }
                    }

                    PrintVertex v = path[i];
                    v.Extrusion = GCodeUtil.Extrude(curA);
                    path.UpdateVertex(i, v);
                }

                prev_path = path;
            }

            NumPaths        = N;
            ExtrusionLength = curA;
        }         // Calculate()