Ejemplo n.º 1
0
        virtual protected bool parse_value_param(string token, int split, int skip, ref GCodeParam param)
        {
            param.identifier = token.Substring(0, split);

            string value = token.Substring(split + skip, token.Length - (split + skip));

            try {
                GCodeUtil.NumberType numType = GCodeUtil.GetNumberType(value);
                if (numType == GCodeUtil.NumberType.Decimal)
                {
                    param.type        = GCodeParam.PType.DoubleValue;
                    param.doubleValue = double.Parse(value);
                    return(true);
                }
                else if (numType == GCodeUtil.NumberType.Integer)
                {
                    param.type     = GCodeParam.PType.IntegerValue;
                    param.intValue = int.Parse(value);
                    return(true);
                }
            } catch {
                // just continue on and do generic string param
            }

            param.type      = GCodeParam.PType.TextValue;
            param.textValue = value;
            return(true);
        }
Ejemplo n.º 2
0
        void emit_linear(GCodeLine line)
        {
            Debug.Assert(line.code == 1);

            double dx = 0, dy = 0;
            bool   brelx = GCodeUtil.TryFindParamNum(line.parameters, "XI", ref dx);
            bool   brely = GCodeUtil.TryFindParamNum(line.parameters, "YI", ref dy);

            LinearMoveData move = new LinearMoveData(new Vector2d(dx, dy));

            if (brelx || brely)
            {
                listener.LinearMoveToRelative2d(move);
                return;
            }

            double x = 0, y = 0;
            bool   absx = GCodeUtil.TryFindParamNum(line.parameters, "X", ref x);
            bool   absy = GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y);

            if (absx && absy)
            {
                listener.LinearMoveToAbsolute2d(move);
                return;
            }

            // [RMS] can we have this??
            if (absx || absy)
            {
                System.Diagnostics.Debug.Assert(false);
            }
        }
Ejemplo n.º 3
0
        virtual protected int is_num_parameter(string token)
        {
            int N = token.Length;

            bool contains_number = false;

            for (int i = 0; i < N && contains_number == false; ++i)
            {
                if (Char.IsDigit(token[i]))
                {
                    contains_number = true;
                }
            }
            if (!contains_number)
            {
                return(-1);
            }

            for (int i = 1; i < N; ++i)
            {
                string sub = token.Substring(i);
                GCodeUtil.NumberType numtype = GCodeUtil.GetNumberType(sub);
                if (numtype != GCodeUtil.NumberType.NotANumber)
                {
                    return(i);
                }
            }
            return(-1);
        }
Ejemplo n.º 4
0
        virtual protected bool parse_code_parameter(string token, ref GCodeParam param)
        {
            param.type       = GCodeParam.PType.Code;
            param.identifier = token.Substring(0, 1);

            string value = token.Substring(1);

            GCodeUtil.NumberType numType = GCodeUtil.GetNumberType(value);
            if (numType == GCodeUtil.NumberType.Integer)
            {
                param.intValue = int.Parse(value);
            }

            return(true);
        }
        // G92 - Position register: Set the specified axes positions to the given position
        // Sets the position of the state machine and the bot. NB: There are two methods of forming the G92 command:
        void set_position(GCodeLine line)
        {
            double x = 0, y = 0, z = 0;

            if (GCodeUtil.TryFindParamNum(line.parameters, "X", ref x))
            {
                CurPosition.x = x;
            }
            if (GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y))
            {
                CurPosition.y = y;
            }
            if (GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z))
            {
                CurPosition.z = z;
            }
        }
Ejemplo n.º 6
0
        void emit_arc(GCodeLine line, bool clockwise)
        {
            double dx = 0, dy = 0;

            // either of these might be missing...
            bool brelx = GCodeUtil.TryFindParamNum(line.parameters, "XI", ref dx);
            bool brely = GCodeUtil.TryFindParamNum(line.parameters, "YI", ref dy);

            Debug.Assert(brelx == true && brely == true);

            double r  = 0;
            bool   br = GCodeUtil.TryFindParamNum(line.parameters, "R", ref r);

            Debug.Assert(br == true);

            // [RMS] seems like G5 always has negative radius and G4 positive ??
            //   (this will tell us)
            Debug.Assert((clockwise && r < 0) || (clockwise == false && r > 0));
            r = Math.Abs(r);

            listener.ArcToRelative2d(new Vector2d(dx, dy), r, clockwise);
        }
Ejemplo n.º 7
0
        virtual protected bool parse_code_parameter(string token, ref GCodeParam param)
        {
            string identifier = token.Substring(0, 1);
            string value      = token.Substring(1);

            switch (GCodeUtil.GetNumberType(value))
            {
            case GCodeUtil.NumberType.Integer:
                param = GCodeParam.Integer(int.Parse(value), identifier);
                break;

            case GCodeUtil.NumberType.Decimal:
                param = GCodeParam.Double(double.Parse(value), identifier);
                break;

            default:
            case GCodeUtil.NumberType.NotANumber:
                param = GCodeParam.Text(value, identifier);
                break;
            }

            return(true);
        }
Ejemplo n.º 8
0
        // G92 - Position register: Set the specified axes positions to the given position
        // Sets the position of the state machine and the bot. NB: There are two methods of forming the G92 command:
        private void set_position(GCodeLine line)
        {
            double x = 0, y = 0, z = 0, a = 0;

            if (GCodeUtil.TryFindParamNum(line.Parameters, "X", ref x))
            {
                CurPosition.x = x;
            }
            if (GCodeUtil.TryFindParamNum(line.Parameters, "Y", ref y))
            {
                CurPosition.y = y;
            }
            if (GCodeUtil.TryFindParamNum(line.Parameters, "Z", ref z))
            {
                CurPosition.z = z;
            }
            if (GCodeUtil.TryFindParamNum(line.Parameters, "A", ref a))
            {
                ExtrusionA = a;
                listener.CustomCommand(
                    (int)CustomListenerCommands.ResetExtruder, GCodeUtil.Extrude(a));
                // reset our state
                in_travel = in_extrude = in_retract = false;
            }

            // E is "current" stepper (A for single extruder)
            double e = 0;

            if (GCodeUtil.TryFindParamNum(line.Parameters, "E", ref e))
            {
                ExtrusionA = e;
                listener.CustomCommand(
                    (int)CustomListenerCommands.ResetExtruder, GCodeUtil.Extrude(e));
                // reset our state
                in_travel = in_extrude = in_retract = false;
            }
        }
        void emit_linear(GCodeLine line)
        {
            Debug.Assert(line.code == 0 || line.code == 1);

            double x         = GCodeUtil.UnspecifiedValue,
                   y         = GCodeUtil.UnspecifiedValue,
                   z         = GCodeUtil.UnspecifiedValue;
            bool     found_x = GCodeUtil.TryFindParamNum(line.parameters, "X", ref x);
            bool     found_y = GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y);
            bool     found_z = GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z);
            Vector3d newPos  = (UseRelativePosition) ? Vector3d.Zero : CurPosition;

            if (found_x)
            {
                newPos.x = x;
            }
            if (found_y)
            {
                newPos.y = y;
            }
            if (found_z)
            {
                newPos.z = z;
            }
            if (UseRelativePosition)
            {
                CurPosition += newPos;
            }
            else
            {
                CurPosition = newPos;
            }

            // F is feed rate (this changes?)
            double f     = 0;
            bool   haveF = GCodeUtil.TryFindParamNum(line.parameters, "F", ref f);

            LinearMoveData move = new LinearMoveData(
                newPos,
                (haveF) ? f : GCodeUtil.UnspecifiedValue);

            bool is_travel = (line.code == 0);

            if (is_travel)
            {
                if (in_travel == false)
                {
                    listener.BeginTravel();
                    in_travel = true;
                    in_cut    = false;
                }
            }
            else
            {
                if (in_cut == false)
                {
                    listener.BeginCut();
                    in_travel = false;
                    in_cut    = true;
                }
            }

            move.source = line;
            Debug.Assert(in_travel || in_cut);
            listener.LinearMoveToAbsolute3d(move);
        }
Ejemplo n.º 10
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 p in Paths)
            {
                if (p is LinearToolpath3 <T> || p is ResetExtruderPathHack)
                {
                    allPaths.Add(p);
                }
            }

            int N = allPaths.Count;

            LinearToolpath3 <T> prev_path = null;

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

                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.FillType.IsPart();
                    var  next_path = (pi < N - 1) ? (allPaths[pi + 1] as LinearToolpath3 <T>) : null;
                    bool next_is_model_deposition =
                        (next_path != null) && (next_path.Type == ToolpathTypes.Deposition) && next_path.FillType.IsPart();
                    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;
                vol_scale = path.FillType.AdjustVolume(vol_scale);

                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.Part.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 < 1e-12);     // next path starts at end of previous!!
                            if (inRetract)
                            {
                                curA     += FixedRetractDistance;
                                inRetract = false;
                            }
                        }
                        else
                        {
                            curPos  = newPos;
                            curRate = newRate;

                            double segment_width = (path[i].Dimensions.x != GCodeUtil.UnspecifiedValue) ?
                                                   path[i].Dimensions.x : path_width;

                            double segment_height = (path[i].Dimensions.y != GCodeUtil.UnspecifiedValue) ?
                                                    path[i].Dimensions.y : path_height;

                            double feed = ExtrusionMath.PathLengthToFilamentLength(
                                segment_height, segment_width, Settings.Material.FilamentDiamMM,
                                dist, vol_scale);

                            // Change the extrusion amount if a modifier is present.
                            // TODO: This is a bit of a hack since the modifier acts on a Vector3d
                            //       and we're ignoring data in the second & third positions.
                            var modifier = path[i]?.ExtendedData?.ExtrusionModifierF;
                            if (modifier != null)
                            {
                                feed = modifier(new Vector3d(feed, 0, 0))[0];
                            }

                            curA += feed;
                        }
                    }

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

                prev_path = path;
            }

            NumPaths        = N;
            ExtrusionLength = curA;
        } // Calculate()
Ejemplo n.º 11
0
        protected virtual void EmitLinear(GCodeLine line)
        {
            Debug.Assert(line.Code == 0 || line.Code == 1);

            double x         = GCodeUtil.UnspecifiedValue,
                   y         = GCodeUtil.UnspecifiedValue,
                   z         = GCodeUtil.UnspecifiedValue;
            bool     found_x = GCodeUtil.TryFindParamNum(line.Parameters, "X", ref x);
            bool     found_y = GCodeUtil.TryFindParamNum(line.Parameters, "Y", ref y);
            bool     found_z = GCodeUtil.TryFindParamNum(line.Parameters, "Z", ref z);
            Vector3d newPos  = (UseRelativePosition) ? Vector3d.Zero : CurPosition;

            if (found_x)
            {
                newPos.x = x;
            }
            if (found_y)
            {
                newPos.y = y;
            }
            if (found_z)
            {
                newPos.z = z;
            }
            if (UseRelativePosition)
            {
                CurPosition += newPos;
            }
            else
            {
                CurPosition = newPos;
            }

            // F is feed rate (this changes?)
            double f     = 0;
            bool   haveF = GCodeUtil.TryFindParamNum(line.Parameters, "F", ref f);

            // A is extrusion stepper. E is also "current" stepper.
            double a     = 0;
            bool   haveA = GCodeUtil.TryFindParamNum(line.Parameters, "A", ref a);

            if (haveA == false)
            {
                haveA = GCodeUtil.TryFindParamNum(line.Parameters, "E", ref a);
            }
            if (UseRelativeExtruder)
            {
                a = ExtrusionA + a;
            }

            LinearMoveData move = new LinearMoveData(
                newPos,
                (haveF) ? f : GCodeUtil.UnspecifiedValue,
                (haveA) ? GCodeUtil.Extrude(a) : GCodeUtil.UnspecifiedPosition);

            if (haveA == false)
            {
                // if we do not have extrusion, this is a travel move
                if (in_travel == false)
                {
                    listener.BeginTravel();
                    in_travel  = true;
                    in_extrude = false;
                }
            }
            else if (in_retract)
            {
                // if we are in retract, we stay in until we see forward movement

                Debug.Assert(in_travel);
                Debug.Assert(a <= LastRetractA + 0.001);
                if (MathUtil.EpsilonEqual(a, LastRetractA, 0.00001))
                {
                    in_retract = false;
                    listener.BeginDeposition();
                    in_extrude = true;
                    in_travel  = false;
                    ExtrusionA = a;
                }
            }
            else if (a < ExtrusionA)
            {
                // if extrusion moved backwards, we need to enter travel

                in_retract   = true;
                LastRetractA = ExtrusionA;
                ExtrusionA   = a;
                if (in_travel == false)
                {
                    listener.BeginTravel();
                    in_travel  = true;
                    in_extrude = false;
                }
            }
            else
            {
                // if we are in travel, we need to begin extruding
                if (in_travel)
                {
                    listener.BeginDeposition();
                    in_travel  = false;
                    in_extrude = true;
                }
                if (in_extrude == false)
                {       // handle initialization cases
                    listener.BeginDeposition();
                    in_extrude = true;
                }
                ExtrusionA = a;
            }

            move.source = line;
            Debug.Assert(in_travel || in_extrude);
            listener.LinearMoveToAbsolute3d(move);
        }
Ejemplo n.º 12
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()