├── gsGCode.asmdef
├── .gitignore
├── assemblers
├── AssemblerUtil.cs
├── ExtrusionMath.cs
├── GenericMillingAssembler.cs
├── RepRapAssembler.cs
├── MakerbotAssembler.cs
├── BaseMillingAssembler.cs
└── BaseDepositionAssembler.cs
├── LICENSE
├── GCodeFile.cs
├── Properties
└── AssemblyInfo.cs
├── writers
├── BaseGCodeWriter.cs
└── StandardGCodeWriter.cs
├── README.md
├── GCodeLine.cs
├── interpreters
├── GCodeInterpreter.cs
├── GCodeToPlanarComplex.cs
├── BiesseInterpreter.cs
├── ThreeAxisCNCInterpreter.cs
└── MakerbotInterpreter.cs
├── settings
├── GenericPrinterSettings.cs
├── RepRapSettings.cs
├── manufacturers.txt
├── MonopriceSettings.cs
├── FlashforgeSettings.cs
├── MakerbotSettings.cs
├── PrintrbotSettings.cs
├── PrusaSettings.cs
└── AdditiveSettings.cs
├── parsers
├── GCodeUtil.cs
└── GenericGCodeParser.cs
└── gsGCode.csproj
/gsGCode.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gsGCode",
3 | "references": [
4 | "geometry3Sharp"
5 | ],
6 | "optionalUnityReferences": [],
7 | "includePlatforms": [],
8 | "excludePlatforms": [],
9 | "allowUnsafeCode": false
10 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 | *.smod
19 |
20 | # Compiled Static libraries
21 | *.lai
22 | *.la
23 | *.a
24 | *.lib
25 |
26 | # Executables
27 | *.exe
28 | *.out
29 | *.app
30 | gsGCode/bin
31 | gsGCode/obj
32 | gsGCode.csproj.user
33 | bin
34 | obj
35 | *.meta
36 |
--------------------------------------------------------------------------------
/assemblers/AssemblerUtil.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using g3;
3 |
4 | namespace gs
5 | {
6 | ///
7 | /// Utility functions for gcode assemblers
8 | ///
9 | public static class AssemblerUtil
10 | {
11 |
12 | ///
13 | /// Calculate distance of filament to extrude to draw path of
14 | /// given length/width/height, for given filament diameter.
15 | ///
16 | public static double CalculateExtrudedFilament(
17 | double pathWidth, double pathHeight, double pathLen,
18 | double filamentDiam )
19 | {
20 | // [RMS] this is just formula form gsSlicer.CalculateExtrusion
21 | double section_area = pathWidth * pathHeight;
22 | double linear_vol = pathLen * section_area;
23 | double fil_rad = filamentDiam / 2;
24 | double fil_area = Math.PI * fil_rad * fil_rad;
25 | double fil_len = linear_vol / fil_area;
26 | return fil_len;
27 | }
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 gradientspace
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/GCodeFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace gs
7 | {
8 |
9 |
10 | public class GCodeFile
11 | {
12 |
13 | List lines;
14 |
15 |
16 |
17 | public GCodeFile()
18 | {
19 | lines = new List();
20 | }
21 |
22 |
23 | public void AppendLine(GCodeLine l)
24 | {
25 | lines.Add(l);
26 | }
27 |
28 |
29 | public int LineCount {
30 | get { return lines.Count; }
31 | }
32 |
33 |
34 | public IEnumerable AllLines()
35 | {
36 | int N = lines.Count;
37 | for (int i = 0; i < N; ++i) {
38 | yield return lines[i];
39 | }
40 | }
41 |
42 |
43 | public IEnumerable AllLinesOfType(GCodeLine.LType eType)
44 | {
45 | int N = lines.Count;
46 | for (int i = 0; i < N; ++i) {
47 | if ( lines[i].type == eType )
48 | yield return lines[i];
49 | }
50 | }
51 |
52 |
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #if !G3_USING_UNITY
2 |
3 | using System.Reflection;
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("gsGCode")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("gradientspae")]
14 | [assembly: AssemblyProduct("gsGCode")]
15 | [assembly: AssemblyCopyright("Copyright © ryan schmidt 2017")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 | [assembly: Guid("25de77c9-14a4-4562-9a24-0bf1e612d9a9")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | // You can specify all the values or you can default the Build and Revision Numbers
35 | // by using the '*' as shown below:
36 | // [assembly: AssemblyVersion("1.0.*")]
37 | [assembly: AssemblyVersion("1.0.0.0")]
38 | [assembly: AssemblyFileVersion("1.0.0.0")]
39 |
40 | #endif
--------------------------------------------------------------------------------
/assemblers/ExtrusionMath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using g3;
3 |
4 | namespace gs
5 | {
6 | ///
7 | /// Utility class for filament extrusion calculations
8 | ///
9 | public static class ExtrusionMath
10 | {
11 |
12 | ///
13 | /// This function computes the amount of filament to extrude (ie how
14 | /// much to turn extruder stepper) along pathLen distance.
15 | /// volumeScale allows for local tuning of this.
16 | ///
17 | public static double PathLengthToFilamentLength(
18 | double layerHeight, double nozzleDiam, double filamentDiam,
19 | double pathLen,
20 | double volumeScale = 1.0)
21 | {
22 | double section_area = nozzleDiam * layerHeight;
23 | double linear_volume = pathLen * section_area;
24 | linear_volume *= volumeScale;
25 |
26 | double filamentRadius = filamentDiam * 0.5;
27 | double filament_section_area = Math.PI * filamentRadius * filamentRadius;
28 | double filament_len = linear_volume / filament_section_area;
29 |
30 | return filament_len;
31 | }
32 |
33 |
34 |
35 | public static double PathLengthToVolume(
36 | double layerHeight, double nozzleDiam,
37 | double pathLen)
38 | {
39 | double section_area = nozzleDiam * layerHeight;
40 | double linear_volume = pathLen * section_area;
41 | return linear_volume;
42 | }
43 |
44 |
45 | public static double WidthFromTargetVolume(
46 | double layerHeight, double pathLen, double targetVolume)
47 | {
48 | return targetVolume / (pathLen * layerHeight);
49 | }
50 |
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/writers/BaseGCodeWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading;
4 | using System.Globalization;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 | public abstract class BaseGCodeWriter
10 | {
11 | ///
12 | /// If the mesh format we are writing is text, then the OS will write in the number style
13 | /// of the current language. So in Germany, numbers are written 1,00 instead of 1.00, for example.
14 | /// If this flag is true, we override this to always write in a consistent way.
15 | ///
16 | public bool WriteInvariantCulture = true;
17 |
18 |
19 | public virtual IOWriteResult WriteFile(GCodeFile file, StreamWriter outStream)
20 | {
21 | // save current culture
22 | var current_culture = Thread.CurrentThread.CurrentCulture;
23 |
24 | try {
25 | if (WriteInvariantCulture)
26 | Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
27 |
28 | foreach ( var line in file.AllLines() )
29 | WriteLine(line, outStream);
30 |
31 | // restore culture
32 | if (WriteInvariantCulture)
33 | Thread.CurrentThread.CurrentCulture = current_culture;
34 |
35 | return IOWriteResult.Ok;
36 |
37 | } catch (Exception e) {
38 | // restore culture
39 | if (WriteInvariantCulture)
40 | Thread.CurrentThread.CurrentCulture = current_culture;
41 | return new IOWriteResult(IOCode.WriterError, "Unknown error : exception : " + e.Message);
42 | }
43 | }
44 |
45 |
46 | public abstract void WriteLine(GCodeLine line, StreamWriter outStream);
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gsGCode
2 |
3 | GCode parsing / manipulation / generation library.
4 |
5 | C#, MIT License. Copyright 2017 ryan schmidt / gradientspace
6 |
7 | Dependencies: [geometry3Sharp](https://github.com/gradientspace/geometry3Sharp) (Boost license)
8 |
9 | questions? get in touch on twitter: [@rms80](http://www.twitter.com/rms80) or [@gradientspace](http://www.twitter.com/gradientspace),
10 | or email [rms@gradientspace.com](mailto:rms@gradientspace.com?subject=gsGCode).
11 |
12 | # What Is This?
13 |
14 | gsGCode is a library for working with GCode. Not just generating GCode, but also reading and manipulating existing GCode files.
15 |
16 | What? Edit a GCode file? that's crazy, right? CAD people used to think the same thing about STL mesh files too.
17 | STL was something you wrote out to communicate with a CNC machine. You might "repair" it, but you didn't edit it.
18 | But then a guy wrote [OpenSCAD](http://www.openscad.org/), and I wrote [Meshmixer](http://www.meshmixer.com), and now STL
19 | files are something that thousands of people open and edit every day.
20 |
21 | The purpose of this library is to make the same thing possible for GCode. GCode is just 3D lines, curves, and
22 | control commands. There is no reason you can't open a GCode file, change one of the paths, and write it back out.
23 | You can easily do that with this library.
24 |
25 | # Can It Write GCode Too?
26 |
27 | Yes! I'm developing gsGCode to support the gradientspace Slicer, which is not released yet. But the low-level GCode generation
28 | infrastructure is all here. You can either use **GCodeBuilder** to construct a **GCodeFile** line-by-line, or an Assembler
29 | (currently only **MakerbotAssembler**) which provides a higher-level turtle-graphics-like API.
30 |
31 | # How?
32 |
33 | See [the wiki](https://github.com/gradientspace/gsGCode/wiki) for what minimal documentation exists right now.
34 | Some sample code will come in time.
35 |
--------------------------------------------------------------------------------
/GCodeLine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 |
10 |
11 |
12 | public struct GCodeParam
13 | {
14 | public enum PType
15 | {
16 | Code,
17 | DoubleValue,
18 | IntegerValue,
19 | TextValue,
20 | NoValue,
21 | Unknown
22 | }
23 |
24 | public PType type;
25 | public string identifier;
26 |
27 | public double doubleValue;
28 | public int intValue {
29 | get { return (int)doubleValue; } // we can store [-2^54, 2^54] precisely in a double
30 | set { doubleValue = value; }
31 | }
32 | public string textValue;
33 | }
34 |
35 |
36 |
37 |
38 | // ugh..class...dangerous!!
39 | public class GCodeLine
40 | {
41 | public enum LType
42 | {
43 | GCode,
44 | MCode,
45 | UnknownCode,
46 |
47 | Comment,
48 | UnknownString,
49 | Blank,
50 |
51 | If,
52 | EndIf,
53 | Else,
54 | UnknownControl
55 | }
56 |
57 |
58 |
59 | public int lineNumber;
60 |
61 | public LType type;
62 | public string orig_string;
63 |
64 | public int N; // N number of line
65 | public int code; // G or M code
66 | public GCodeParam[] parameters; // arguments/parameters
67 |
68 | public string comment;
69 |
70 | public GCodeLine(int num, LType type)
71 | {
72 | lineNumber = num;
73 | this.type = type;
74 |
75 | orig_string = null;
76 | N = code = -1;
77 | parameters = null;
78 | comment = null;
79 | }
80 |
81 | public GCodeLine(int lineNum, LType type, string comment) {
82 | lineNumber = lineNum;
83 | this.type = type;
84 | if ( type == LType.UnknownString ) {
85 | this.orig_string = comment;
86 | } else {
87 | this.comment = comment;
88 | }
89 | }
90 |
91 |
92 | public virtual GCodeLine Clone() {
93 | GCodeLine clone = new GCodeLine(this.lineNumber, this.type);
94 | clone.orig_string = this.orig_string;
95 | clone.N = this.N;
96 | clone.code = this.code;
97 | if ( this.parameters != null ) {
98 | clone.parameters = new GCodeParam[this.parameters.Length];
99 | for (int i = 0; i < this.parameters.Length; ++i )
100 | clone.parameters[i] = this.parameters[i];
101 | }
102 | clone.comment = this.comment;
103 | return clone;
104 | }
105 |
106 | }
107 |
108 |
109 | }
--------------------------------------------------------------------------------
/interpreters/GCodeInterpreter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 |
10 | public struct InterpretArgs
11 | {
12 | public GCodeLine.LType eTypeFilter;
13 |
14 |
15 | public bool HasTypeFilter { get { return eTypeFilter != GCodeLine.LType.Blank; } }
16 |
17 | public static readonly InterpretArgs Default = new InterpretArgs() {
18 | eTypeFilter = GCodeLine.LType.Blank
19 | };
20 | }
21 |
22 |
23 | public interface IGCodeInterpreter
24 | {
25 | void AddListener(IGCodeListener listener);
26 | void Interpret(GCodeFile file, InterpretArgs args);
27 | }
28 |
29 |
30 | ///
31 | /// GCodeInterpreter passes this to GCodeListener for each G1 line
32 | ///
33 | public struct LinearMoveData {
34 |
35 | public Vector3d position;
36 | public double rate;
37 | public Vector3d extrude;
38 | public GCodeLine source;
39 |
40 | public LinearMoveData(Vector2d pos,
41 | double rateIn = GCodeUtil.UnspecifiedValue ) {
42 | position = new Vector3d(pos.x, pos.y, GCodeUtil.UnspecifiedValue);
43 | rate = rateIn;
44 | extrude = GCodeUtil.UnspecifiedPosition;
45 | source = null;
46 | }
47 | public LinearMoveData(Vector3d pos, double rateIn = GCodeUtil.UnspecifiedValue) {
48 | position = pos;
49 | rate = rateIn;
50 | extrude = GCodeUtil.UnspecifiedPosition;
51 | source = null;
52 | }
53 | public LinearMoveData(Vector3d pos, double rateIn, Vector3d extrudeIn) {
54 | position = pos;
55 | rate = rateIn;
56 | extrude = extrudeIn;
57 | source = null;
58 | }
59 | }
60 |
61 |
62 | // codes to pass to IGCodeListener.CustomCommand
63 | // this is basically just slightly better than complete hacks
64 | public enum CustomListenerCommands
65 | {
66 | ResetPosition = 0, // object should be Vector3d
67 | ResetExtruder = 1 // object should be Vector3d
68 |
69 | }
70 |
71 |
72 | public interface IGCodeListener
73 | {
74 | void Begin();
75 | void End();
76 |
77 | void BeginTravel();
78 | void BeginDeposition();
79 | void BeginCut();
80 |
81 | // for hacks
82 | void CustomCommand(int code, object o);
83 |
84 | void LinearMoveToAbsolute2d(LinearMoveData move);
85 | void LinearMoveToRelative2d(LinearMoveData move);
86 | void ArcToRelative2d(Vector2d pos, double radius, bool clockwise, double rate = 0);
87 |
88 | void LinearMoveToAbsolute3d(LinearMoveData move);
89 | void LinearMoveToRelative3d(LinearMoveData move);
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/settings/GenericPrinterSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public class GenericPrinterSettings : GenericRepRapSettings
9 | {
10 | public override AssemblerFactoryF AssemblerType() {
11 | return RepRapAssembler.Factory;
12 | }
13 |
14 | public string ManufacturerName;
15 | public string ManufacturerUUID;
16 | public string DefaultMachineUUID;
17 |
18 | public GenericPrinterSettings(string mfgName, string mfgUUID, string defaultMachineUUID) {
19 | ManufacturerName = mfgName;
20 | ManufacturerUUID = mfgUUID;
21 | DefaultMachineUUID = defaultMachineUUID;
22 |
23 | configure_unknown();
24 | }
25 |
26 |
27 | public override T CloneAs() {
28 | GenericPrinterSettings copy = new GenericPrinterSettings(ManufacturerName, ManufacturerUUID, DefaultMachineUUID);
29 | this.CopyFieldsTo(copy);
30 | return copy as T;
31 | }
32 |
33 |
34 | void configure_unknown()
35 | {
36 | Machine.ManufacturerName = ManufacturerName;
37 | Machine.ManufacturerUUID = ManufacturerUUID;
38 | Machine.ModelIdentifier = "Unknown";
39 | Machine.ModelUUID = DefaultMachineUUID;
40 | Machine.Class = MachineClass.PlasticFFFPrinter;
41 | Machine.BedSizeXMM = 80;
42 | Machine.BedSizeYMM = 80;
43 | Machine.MaxHeightMM = 55;
44 | Machine.NozzleDiamMM = 0.4;
45 | Machine.FilamentDiamMM = 1.75;
46 |
47 | Machine.MaxExtruderTempC = 230;
48 | Machine.HasHeatedBed = false;
49 | Machine.MaxBedTempC = 60;
50 |
51 | Machine.MaxExtrudeSpeedMMM = 50 * 60;
52 | Machine.MaxTravelSpeedMMM = 150 * 60;
53 | Machine.MaxZTravelSpeedMMM = 100 * 60;
54 | Machine.MaxRetractSpeedMMM = 40 * 60;
55 | Machine.MinLayerHeightMM = 0.1;
56 | Machine.MaxLayerHeightMM = 0.3;
57 |
58 | LayerHeightMM = 0.2;
59 |
60 | ExtruderTempC = 200;
61 | HeatedBedTempC = 0;
62 |
63 | SolidFillNozzleDiamStepX = 1.0;
64 | RetractDistanceMM = 4.5;
65 |
66 | RetractSpeed = Machine.MaxRetractSpeedMMM;
67 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
68 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
69 | CarefulExtrudeSpeed = 20 * 60;
70 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
71 | OuterPerimeterSpeedX = 0.5;
72 | }
73 |
74 |
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/settings/RepRapSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class RepRap
9 | {
10 | public const string UUID = "e95dcaaa-4315-412f-bd80-5049fb74f384";
11 |
12 | public enum Models {
13 | Unknown = 0
14 | };
15 |
16 | public const string UUID_Unknown = "bb097486-bb07-4a95-950f-1a1de992e782";
17 | }
18 |
19 |
20 | public class RepRapSettings : GenericRepRapSettings
21 | {
22 | public RepRap.Models ModelEnum;
23 |
24 | public override AssemblerFactoryF AssemblerType() {
25 | return RepRapAssembler.Factory;
26 | }
27 |
28 |
29 | public RepRapSettings(RepRap.Models model) {
30 | ModelEnum = model;
31 |
32 | if (model == RepRap.Models.Unknown)
33 | configure_unknown();
34 | }
35 |
36 | public override T CloneAs() {
37 | RepRapSettings copy = new RepRapSettings(this.ModelEnum);
38 | this.CopyFieldsTo(copy);
39 | return copy as T;
40 | }
41 |
42 | public static IEnumerable EnumerateDefaults()
43 | {
44 | yield return new RepRapSettings(RepRap.Models.Unknown);
45 | }
46 |
47 |
48 | void configure_unknown()
49 | {
50 | Machine.ManufacturerName = "RepRap";
51 | Machine.ManufacturerUUID = RepRap.UUID;
52 | Machine.ModelIdentifier = "Unknown";
53 | Machine.ModelUUID = RepRap.UUID_Unknown;
54 | Machine.Class = MachineClass.PlasticFFFPrinter;
55 | Machine.BedSizeXMM = 80;
56 | Machine.BedSizeYMM = 80;
57 | Machine.BedOriginFactorX = 0.5;
58 | Machine.BedOriginFactorY = 0.5;
59 |
60 | Machine.MaxHeightMM = 55;
61 | Machine.NozzleDiamMM = 0.4;
62 | Machine.FilamentDiamMM = 1.75;
63 |
64 | Machine.MaxExtruderTempC = 230;
65 | Machine.HasHeatedBed = false;
66 | Machine.MaxBedTempC = 60;
67 |
68 | Machine.MaxExtrudeSpeedMMM = 50 * 60;
69 | Machine.MaxTravelSpeedMMM = 150 * 60;
70 | Machine.MaxZTravelSpeedMMM = 100 * 60;
71 | Machine.MaxRetractSpeedMMM = 40 * 60;
72 | Machine.MinLayerHeightMM = 0.1;
73 | Machine.MaxLayerHeightMM = 0.3;
74 |
75 | LayerHeightMM = 0.2;
76 |
77 | ExtruderTempC = 200;
78 | HeatedBedTempC = 0;
79 |
80 | SolidFillNozzleDiamStepX = 1.0;
81 | RetractDistanceMM = 4.5;
82 |
83 | RetractSpeed = Machine.MaxRetractSpeedMMM;
84 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
85 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
86 | CarefulExtrudeSpeed = 20 * 60;
87 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
88 | OuterPerimeterSpeedX = 0.5;
89 | }
90 |
91 |
92 | }
93 |
94 | }
--------------------------------------------------------------------------------
/parsers/GCodeUtil.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 | static public class GCodeUtil
10 | {
11 | public const double UnspecifiedValue = double.MaxValue;
12 | public static readonly Vector3d UnspecifiedPosition = Vector3d.MaxValue;
13 | public static readonly Vector2d UnspecifiedDimensions = Vector2d.MaxValue;
14 |
15 | public static Vector3d Extrude(double a) {
16 | return new Vector3d(a, UnspecifiedValue, UnspecifiedValue);
17 | }
18 |
19 |
20 | // returns index of param, or -1
21 | static public int TryFindParam(GCodeParam[] paramList, string identifier )
22 | {
23 | for (int i = 0; i < paramList.Length; ++i)
24 | if (paramList[i].identifier == identifier)
25 | return i;
26 | return -1;
27 | }
28 |
29 | static public bool TryFindParamNum(GCodeParam[] paramList, string identifier, ref double d)
30 | {
31 | if (paramList == null )
32 | return false;
33 | for (int i = 0; i < paramList.Length; ++i) {
34 | if (paramList[i].identifier == identifier) {
35 | if (paramList[i].type == GCodeParam.PType.DoubleValue) {
36 | d = paramList[i].doubleValue;
37 | return true;
38 | } else if (paramList[i].type == GCodeParam.PType.IntegerValue) {
39 | d = paramList[i].intValue;
40 | return true;
41 | } else
42 | return false;
43 | }
44 | }
45 | return false;
46 | }
47 |
48 |
49 |
50 | public enum NumberType
51 | {
52 | Integer, Decimal, NotANumber
53 | }
54 |
55 | // doesn't handle e^ numbers
56 | // doesn't allow commas
57 | static public NumberType GetNumberType(string s)
58 | {
59 | int N = s.Length;
60 |
61 | bool saw_digit = false;
62 | bool saw_dot = false;
63 | bool saw_sign = false;
64 | for (int i = 0; i < N; ++i) {
65 | char c = s[i];
66 | if ( c == '-' ) {
67 | if (saw_digit || saw_dot || saw_sign)
68 | return NumberType.NotANumber;
69 | saw_sign = true;
70 | } else if ( c == '.' ) {
71 | if (saw_dot)
72 | return NumberType.NotANumber;
73 | saw_dot = true;
74 | } else if (Char.IsDigit(c)) {
75 | saw_digit = true;
76 | } else {
77 | return NumberType.NotANumber;
78 | }
79 | }
80 | if (!saw_digit)
81 | return NumberType.NotANumber;
82 | return (saw_dot) ? NumberType.Decimal : NumberType.Integer;
83 | }
84 |
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/assemblers/GenericMillingAssembler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 | using gs;
7 |
8 | namespace gs
9 | {
10 |
11 | public class GenericMillingAssembler : BaseMillingAssembler
12 | {
13 | public static BaseMillingAssembler Factory(GCodeBuilder builder, SingleMaterialFFFSettings settings) {
14 | return new GenericMillingAssembler(builder, settings);
15 | }
16 |
17 |
18 | public SingleMaterialFFFSettings Settings;
19 |
20 |
21 | public GenericMillingAssembler(GCodeBuilder useBuilder, SingleMaterialFFFSettings settings) : base(useBuilder, settings.Machine)
22 | {
23 | Settings = settings;
24 |
25 | OmitDuplicateZ = true;
26 | OmitDuplicateF = true;
27 |
28 | HomeSequenceF = StandardHomeSequence;
29 | }
30 |
31 |
32 | public override void UpdateProgress(int i) {
33 | // not supported on reprap?
34 | //Builder.BeginMLine(73).AppendI("P",i);
35 | }
36 |
37 | public override void ShowMessage(string s)
38 | {
39 | Builder.AddCommentLine(s);
40 | }
41 |
42 |
43 | ///
44 | /// Replace this to run your own home sequence
45 | ///
46 | public Action HomeSequenceF;
47 |
48 |
49 | public enum HeaderState
50 | {
51 | AfterComments,
52 | BeforeHome
53 | };
54 | public Action HeaderCustomizerF = (state, builder) => { };
55 |
56 |
57 |
58 |
59 | public override void AppendHeader() {
60 | AppendHeader_StandardRepRap();
61 | }
62 | void AppendHeader_StandardRepRap() {
63 |
64 | base.AddStandardHeader(Settings);
65 |
66 | HeaderCustomizerF(HeaderState.AfterComments, Builder);
67 |
68 | Builder.BeginGLine(21, "units=mm");
69 | Builder.BeginGLine(90, "absolute positions");
70 |
71 | HeaderCustomizerF(HeaderState.BeforeHome, Builder);
72 |
73 | HomeSequenceF(Builder);
74 |
75 | // retract to retract height
76 | //Builder.BeginGLine(0, "retract to top").AppendI("X", 0).AppendI("Y", 0).AppendF("Z", Settings.RetractDistanceMM);
77 |
78 | //PositionShift = 0.5 * new Vector2d(Settings.Machine.BedSizeXMM, Settings.Machine.BedSizeYMM);
79 | //PositionShift = Vector2d.Zero;
80 | currentPos = Vector3d.Zero;
81 |
82 | ShowMessage("Cut Started");
83 |
84 | in_travel = false;
85 |
86 | UpdateProgress(0);
87 | }
88 |
89 |
90 |
91 |
92 | public override void AppendFooter() {
93 | AppendFooter_StandardRepRap();
94 | }
95 | void AppendFooter_StandardRepRap() {
96 |
97 | UpdateProgress(100);
98 |
99 | Builder.AddCommentLine("End of print");
100 | ShowMessage("Done!");
101 |
102 | Builder.BeginMLine(30, "end program");
103 |
104 | Builder.EndLine(); // need to force this
105 | }
106 |
107 |
108 |
109 |
110 | public virtual void StandardHomeSequence(GCodeBuilder builder)
111 | {
112 | //Builder.BeginGLine(0, "home x/y/z").AppendI("X", 0).AppendI("Y", 0).AppendI("Z", 0);
113 | }
114 |
115 |
116 | }
117 |
118 |
119 | }
--------------------------------------------------------------------------------
/writers/StandardGCodeWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Text;
4 | using System.IO;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 | public class StandardGCodeWriter : BaseGCodeWriter
10 | {
11 | int float_precision = 5;
12 | string float_format = "{0:0.#####}";
13 | public int FloatPrecision {
14 | get { return float_precision; }
15 | set { float_precision = value;
16 | float_format = "{0:0." + new String('#',float_precision) + "}";
17 | }
18 | }
19 |
20 |
21 | public enum CommentStyles
22 | {
23 | Semicolon = 0,
24 | Bracket = 1
25 | }
26 | public CommentStyles CommentStyle = CommentStyles.Semicolon;
27 |
28 |
29 |
30 | public override void WriteLine(GCodeLine line, StreamWriter outStream)
31 | {
32 | if ( line.type == GCodeLine.LType.Comment ) {
33 | if (CommentStyle == CommentStyles.Semicolon) {
34 | if (line.comment[0] != ';')
35 | outStream.Write(";");
36 | outStream.WriteLine(line.comment);
37 | } else {
38 | outStream.Write("(");
39 | outStream.Write(line.comment);
40 | outStream.WriteLine(")");
41 | }
42 | return;
43 | } else if ( line.type == GCodeLine.LType.UnknownString ) {
44 | outStream.WriteLine(line.orig_string);
45 | return;
46 | } else if ( line.type == GCodeLine.LType.Blank ) {
47 | return;
48 | }
49 |
50 | StringBuilder b = new StringBuilder();
51 | if ( line.type == GCodeLine.LType.MCode ) {
52 | b.Append('M');
53 | } else if (line.type == GCodeLine.LType.GCode ) {
54 | b.Append('G');
55 | } else {
56 | throw new Exception("StandardGCodeWriter.WriteLine: unsupported line type");
57 | }
58 |
59 | b.Append(line.code);
60 | b.Append(' ');
61 |
62 | if ( line.parameters != null ) {
63 | foreach ( GCodeParam p in line.parameters ) {
64 | if ( p.type == GCodeParam.PType.Code ) {
65 | //
66 | } else if ( p.type == GCodeParam.PType.IntegerValue ) {
67 | b.Append(p.identifier);
68 | b.Append(p.intValue);
69 | b.Append(' ');
70 | } else if ( p.type == GCodeParam.PType.DoubleValue ) {
71 | b.Append(p.identifier);
72 | b.AppendFormat(float_format, p.doubleValue);
73 | b.Append(' ');
74 | } else if ( p.type == GCodeParam.PType.TextValue) {
75 | b.Append(p.identifier);
76 | b.Append(p.textValue);
77 | b.Append(' ');
78 | } else if ( p.type == GCodeParam.PType.NoValue) {
79 | b.Append(p.identifier);
80 | b.Append(' ');
81 | } else {
82 | throw new Exception("StandardGCodeWriter.WriteLine: unsupported parameter type");
83 | }
84 | }
85 | }
86 |
87 |
88 | if ( line.comment != null && line.comment.Length > 0 ) {
89 | if (CommentStyle == CommentStyles.Semicolon) {
90 | if (line.comment[0] != '(' && line.comment[0] != ';')
91 | b.Append(';');
92 | b.Append(line.comment);
93 | } else {
94 | b.Append("(");
95 | b.Append(line.comment);
96 | b.Append(")");
97 | }
98 | }
99 |
100 | outStream.WriteLine(b.ToString());
101 | }
102 |
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/interpreters/GCodeToPlanarComplex.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Diagnostics;
6 | using g3;
7 |
8 | namespace gs
9 | {
10 | public class GCodeToPlanarComplex : IGCodeListener
11 | {
12 | public PlanarComplex Complex = new PlanarComplex();
13 |
14 | Vector2d P;
15 |
16 |
17 | public void Begin()
18 | {
19 | P = Vector2d.Zero;
20 | }
21 | public void End()
22 | {
23 | }
24 |
25 | // not sure what to do with these...
26 | public void BeginTravel() {
27 | }
28 | public void BeginDeposition() {
29 | }
30 | public void BeginCut()
31 | {
32 | }
33 |
34 | public void LinearMoveToAbsolute2d(LinearMoveData move)
35 | {
36 | Vector2d P2 = move.position.xy;
37 | Complex.Add(new Segment2d(P, P2));
38 | P = P2;
39 | }
40 |
41 | public void LinearMoveToRelative2d(LinearMoveData move)
42 | {
43 | Vector2d P2 = P + move.position.xy;
44 | Complex.Add(new Segment2d(P, P2));
45 | P = P2;
46 | }
47 |
48 |
49 | public void LinearMoveToAbsolute3d(LinearMoveData move)
50 | {
51 | throw new NotSupportedException();
52 | }
53 |
54 | public void LinearMoveToRelative3d(LinearMoveData move)
55 | {
56 | throw new NotSupportedException();
57 | }
58 |
59 |
60 | int find_arc_centers(Vector2d p1, Vector2d p2, double radius, out Vector2d c0, out Vector2d c1)
61 | {
62 | c0 = c1 = Vector2d.Zero;
63 |
64 | double dist2 = p1.DistanceSquared(p2);
65 | double diam2 = 4 * radius * radius;
66 | Debug.Assert(diam2 > dist2); // otherwise solution is impossible
67 |
68 | Vector2d midpoint = 0.5 * (p1 + p2);
69 | if ( MathUtil.EpsilonEqual(dist2, diam2, MathUtil.ZeroTolerance) ) {
70 | c0 = midpoint;
71 | return 1;
72 | }
73 |
74 | double d = Math.Sqrt(radius * radius - dist2 / 4);
75 | double distance = Math.Sqrt(dist2);
76 | double ox = d * (p2.x - p1.x) / distance;
77 | double oy = d * (p2.y - p1.y) / distance;
78 | c0 = new Vector2d(midpoint.x - oy, midpoint.y + ox);
79 | c1 = new Vector2d(midpoint.x + oy, midpoint.y - ox);
80 | return 2;
81 | }
82 |
83 |
84 | double arc_angle_deg(Vector2d p, Vector2d c) {
85 | Vector2d v = p - c;
86 | v.Normalize();
87 | double angle = Math.Atan2(v.y, v.x);
88 | return angle * MathUtil.Rad2Deg;
89 | }
90 |
91 |
92 | bool arc_is_cw( Vector2d p1, Vector2d p2, Vector2d c ) {
93 | return false;
94 | }
95 |
96 |
97 | public void ArcToRelative2d(Vector2d v, double radius, bool clockwise, double rate = 0)
98 | {
99 | Vector2d P2 = P + v;
100 |
101 | Vector2d c0,c1;
102 | int nCenters = find_arc_centers(P, P2, radius, out c0, out c1);
103 |
104 | //bool b0Left = MathUtil.IsLeft(P, P2, c0) > 0;
105 | //bool b1Left = MathUtil.IsLeft(P, P2, c1) > 0;
106 |
107 | Vector2d c = c0;
108 | if (nCenters == 2 && clockwise == false )
109 | c = c1;
110 |
111 | // [RMS] what does negative radius mean ??
112 | //bool reverse = false;
113 | //if (radius < 0)
114 | // reverse = true;
115 | radius = Math.Abs(radius);
116 |
117 | double start_angle = arc_angle_deg(P, c);
118 | double end_angle = arc_angle_deg(P2, c);
119 | if ( clockwise == false ) {
120 | double tmp = start_angle; start_angle = end_angle; end_angle = tmp;
121 | }
122 |
123 |
124 | Arc2d arc = new Arc2d(c, radius, start_angle, end_angle);
125 | //if (reverse)
126 | // arc.Reverse();
127 | Complex.Add(arc);
128 |
129 | P = P2;
130 | }
131 |
132 |
133 | public void CustomCommand(int code, object o) {
134 | // ignore all for now
135 | }
136 |
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/interpreters/BiesseInterpreter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Diagnostics;
6 | using g3;
7 |
8 | namespace gs
9 | {
10 | public class BiesseInterpreter : IGCodeInterpreter
11 | {
12 | IGCodeListener listener = null;
13 | Dictionary> GCodeMap = new Dictionary>();
14 |
15 |
16 | public BiesseInterpreter()
17 | {
18 | build_maps();
19 | }
20 |
21 |
22 |
23 | public virtual void AddListener(IGCodeListener listener) {
24 | if (this.listener != null)
25 | throw new Exception("Only one listener supported!");
26 | this.listener = listener;
27 | }
28 |
29 | public virtual void Interpret(GCodeFile file, InterpretArgs args)
30 | {
31 | IEnumerable lines_enum =
32 | (args.HasTypeFilter) ? file.AllLines() : file.AllLinesOfType(args.eTypeFilter);
33 |
34 | listener.Begin();
35 |
36 | foreach(GCodeLine line in lines_enum) {
37 |
38 | if ( line.type == GCodeLine.LType.GCode ) {
39 | Action parseF;
40 | if (GCodeMap.TryGetValue(line.code, out parseF))
41 | parseF(line);
42 | }
43 |
44 | }
45 |
46 | listener.End();
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | void emit_linear(GCodeLine line)
57 | {
58 | Debug.Assert(line.code == 1);
59 |
60 | double dx = 0, dy = 0;
61 | bool brelx = GCodeUtil.TryFindParamNum(line.parameters, "XI", ref dx);
62 | bool brely = GCodeUtil.TryFindParamNum(line.parameters, "YI", ref dy);
63 |
64 | LinearMoveData move = new LinearMoveData(new Vector2d(dx,dy));
65 |
66 | if (brelx || brely) {
67 | listener.LinearMoveToRelative2d(move);
68 | return;
69 | }
70 |
71 | double x = 0, y = 0;
72 | bool absx = GCodeUtil.TryFindParamNum(line.parameters, "X", ref x);
73 | bool absy = GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y);
74 | if ( absx && absy ) {
75 | listener.LinearMoveToAbsolute2d(move);
76 | return;
77 | }
78 |
79 | // [RMS] can we have this??
80 | if (absx || absy)
81 | System.Diagnostics.Debug.Assert(false);
82 | }
83 |
84 |
85 |
86 | void emit_cw_arc(GCodeLine line) {
87 | emit_arc(line, true);
88 | }
89 | void emit_ccw_arc(GCodeLine line) {
90 | emit_arc(line, false);
91 | }
92 |
93 | void emit_arc(GCodeLine line, bool clockwise) {
94 |
95 | double dx = 0, dy = 0;
96 |
97 | // either of these might be missing...
98 | bool brelx = GCodeUtil.TryFindParamNum(line.parameters, "XI", ref dx);
99 | bool brely = GCodeUtil.TryFindParamNum(line.parameters, "YI", ref dy);
100 | Debug.Assert(brelx == true && brely == true);
101 |
102 | double r = 0;
103 | bool br = GCodeUtil.TryFindParamNum(line.parameters, "R", ref r);
104 | Debug.Assert(br == true);
105 |
106 | // [RMS] seems like G5 always has negative radius and G4 positive ??
107 | // (this will tell us)
108 | Debug.Assert((clockwise && r < 0) || (clockwise == false && r > 0));
109 | r = Math.Abs(r);
110 |
111 | listener.ArcToRelative2d( new Vector2d(dx,dy), r, clockwise );
112 | }
113 |
114 |
115 | void build_maps()
116 | {
117 |
118 | // G1 = linear move
119 | GCodeMap[1] = emit_linear;
120 |
121 | // G4 = CCW circular
122 | GCodeMap[4] = emit_ccw_arc;
123 | GCodeMap[5] = emit_cw_arc;
124 | }
125 |
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/gsGCode.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {25DE77C9-14A4-4562-9A24-0BF1E612D9A9}
8 | Library
9 | Properties
10 | gs
11 | gsGCode
12 | v4.6
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | AnyCPU
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | AnyCPU
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | {0c518dda-28fe-44ca-9ab0-f9773974f13a}
79 | geometry3Sharp
80 |
81 |
82 |
83 |
90 |
--------------------------------------------------------------------------------
/settings/manufacturers.txt:
--------------------------------------------------------------------------------
1 | 3D Systems,94b7a2ac-ccac-4a71-b21d-cb88e2a07378,7f898fc4-1e2a-4bb0-b1c9-b5d8e140a31d
2 | Airwolf 3D,79b0ce85-e8c0-437b-b6a8-6fca0d799f27,276dc7d0-f03e-4b11-b20b-0f0ed13d9d30
3 | Afinia,d25ef920-9e97-4204-8ee8-c6af5ca91a34,50e1edfa-d021-4db2-a032-132d54be5d69
4 | AON 3D,81935c8d-352d-4cc6-9491-e235912a6f58,bcd3120c-818f-4d58-9c08-91c4c70a0bea
5 | Arcam,d4464797-8ac0-4de8-8929-aea175caf74d,9f6b12a3-986c-424f-9765-7d870d3acfd1
6 | Autodesk,5bb78a3d-1f53-43a2-8cac-fbce92a410c1,01c3ccad-18d2-49ce-aa96-7dabb6a871c5
7 | B9 Creations,3c695645-2bc9-4683-8d2b-f3d50383b6fd,be4d0871-406c-41a9-bec1-2d4723abdc59
8 | BCN3D,a5dcc576-2bb5-4855-bbe9-46a9285966ed,d0a133ea-355a-49df-a0e2-d43750cc3fae
9 | BEEVERYCREATIVE,c6801cdc-9ad9-4a93-9244-ea36c2d1aee0,73b4fda0-d83d-42a7-a394-b2b7cfcdcaae
10 | BigRep,737eef0a-2648-434b-b3e2-fc9ef3b2af79,65f1b193-7260-4b97-8896-e5f100bc51fa
11 | BQ,37d83f7f-ffc4-41d4-ba51-babe7b58ab28,b3d1fb5f-b73b-456e-a070-8394d7a0aff1
12 | Carbon,60d0408c-01d9-4d58-8aee-39992c7c9ff8,9ff8fcc7-f395-49d7-8834-47efb37f81c0
13 | CEL,70bf21b6-9cca-455d-ab5c-689e89d917f4,4660bb09-197b-4fa5-b6cf-f6a0ebb0bdb6
14 | Cetus3D,ba6588df-3efe-4718-a820-f37f07c4273c,023eaad7-94ac-4393-8212-708ca8ff4fc6
15 | ConceptLaser,b327511b-5e1f-4e3f-af04-da4604a8d898,e4b2bba5-1147-451a-a124-d67927ce80f7
16 | CraftUnique,b5277ab8-0804-4a42-ad46-625b4e939879,59105b59-1751-4242-97e2-dfa9882d9d70
17 | Creality,d31a921f-0c3e-40fb-8d6d-19bce9767a47,e99dad60-60db-409b-9cec-ef4a40bc3f12
18 | Dremel,98084da7-82e1-4d38-9954-d9016e49e767,0d37a5e8-0d27-475c-8d02-80fbfefaf905
19 | EnvisionTEC,dc35e446-67c5-4171-a9d4-85bca099b6af,73e5a4a3-91a1-43a8-a7f5-095fc1518a2c
20 | EOS,9e66dc8e-b524-46fc-9725-a745cd16c6ea,4dc95818-1f68-4975-99a0-770e42891508
21 | ExOne,f8826e0e-28b1-4220-8185-442afda7fab1,9dac5954-16bd-4256-bf59-7e3e3186bcc6
22 | FlashForge,5974064e-8751-4048-a700-73a023add74f,f387a3d4-ba39-4a60-9e68-93ce7af4d92a
23 | Formlabs,aad64234-0bdd-43b9-97a2-89b5d801754c,7634cb5d-6c0b-4eef-bdd4-1ed0886181c2
24 | HICTOP,52983236-3d5c-4875-bf7d-825608e6f7dd,5418c66a-9b67-461f-88b4-afec771c300e
25 | HP,f08420a3-98fd-4d8c-b6b1-410395837087,f456f367-25e2-485a-9b68-201db722fa04
26 | Hyvision,b0765b0c-d40a-4b74-bef7-d702db3b3269,67cf37bd-d10d-4933-9d78-0e10e6eda4cb
27 | Leapfrog,66a66dcb-b4ca-48c6-99d4-8e6119c60af9,ee82152f-bc97-4b1d-9cc2-4bfaeb89da87
28 | Lulzbot,2b2419af-5ae8-4b08-9434-cb619c0e7b13,839770e8-654b-427f-ad0c-296b4c79acb2
29 | M3D,8ba4493a-90bd-4ae5-b777-22f26b0f2ef8,1796376e-54e1-4bfc-88a5-156cae9bb6cf
30 | Markforged,70377286-8692-415d-9449-04af1712b939,5d94c2d3-2b38-4503-8ffb-c9e11b0d4f91
31 | Makerbot,77b7ed08-dcc8-4c2e-a189-18aa549bf94b,625aa5dc-8e9d-4240-86ff-8bc369cd5124
32 | Makergear,d7763933-bf59-4c7d-ad80-0f7ecd3bd925,54f9de24-2c3d-48c6-8d35-3a55e016f8c6
33 | Mcor,1918a2f0-543d-49c8-af29-b3e3983a35f4,3c693662-fe56-4531-b7f8-f3bc9b0fcecf
34 | Monoprice,860432eb-dec6-4b20-8f97-3643a50daf1d,409e843b-c1d0-45fc-82d1-d7cc5635b8ee
35 | New Matter,fa938c28-612b-4efb-99e6-bc64bdf2ed7e,44bcfd43-f041-46e9-a40b-8c96618abbe0
36 | Printrbot,10dd0db9-df41-4b3e-8b73-d345c408b5ff,9a4cc498-376a-4780-956c-d0e145751868
37 | Prusa Research,4530287d-cd23-416c-b74b-4876c385750a,fc09f99c-aee0-45e9-bca3-3e088ccb0b55
38 | Sharebot,af512da8-3dab-4e14-88b1-fdce4508fc99,0dc584bb-de1a-479b-97bf-70d32ab66a5e
39 | SeeMeCNC,7964ea72-74b0-46b0-951e-6f7ba9aff565,5284e874-6cfc-470a-9530-7fc927b894eb
40 | Solidoodle,291a28dd-92a2-46c0-92eb-c1d786830000,1b38daf5-edd9-4839-ade0-d80c4de47059
41 | Raise3D,7c28bf29-6876-4eea-b703-2d63f08198e9,1f1199d1-4667-4981-99b8-23e3d246fd8a
42 | Renishaw,95b96935-14ed-44dd-a3c5-b9a4acb18725,a3317353-e781-4c4f-afe2-a4242fe2e7cb
43 | RepRap,e95dcaaa-4315-412f-bd80-5049fb74f384,bb097486-bb07-4a95-950f-1a1de992e782
44 | Robo3D,178bff03-c02d-4c6a-b255-9c914937d18e,10636e51-c1ad-430a-9ca1-1fdeba23f536
45 | Stratasys,34a02b0d-b5c0-4282-bba5-0c455ece5bf4,749235cd-3c10-450d-bf33-bfb8b1c16beb
46 | Tevo,b05970de-a552-4d24-b938-a48638d0d967,9e0bee29-54cb-419a-bb5f-5375d470ffb8
47 | Tinkerines,1e3fdd02-d907-4990-b4eb-b1e72ea20bfa,d5a44850-ac45-4180-b491-edb0358244ba
48 | Type A,66a0f1f1-e5da-4af4-88e0-c2945f7499bc,477a9bca-fe98-4c2a-94bb-3b1ebba83171
49 | Ultimaker,4d34d642-f1a1-4009-8ee0-60f7d1bdeb28,017f7ea4-ce20-4686-b1b5-410870db41a2
50 | UP3D,0dd0b76c-2014-40ac-843f-e8a70dc91b77,09d7ab84-89cd-4f0a-af5b-be434ab43a3c
51 | Velleman,d47e667a-e496-4626-8c98-a96725071b8e,ef2dc71a-a72f-4049-bf14-4b8172fd738c
52 | Voxeljet,239aa7e7-6a3a-4e5d-8688-acafe5bea792,0b3ca452-4988-4bdf-b9d2-19565c62d46e
53 | WASP,590ea63b-52b4-4f81-a5dd-c1332918ac07,595799cc-e543-4e80-a1fe-a895c6bb304c
54 | Wanhao,17c056dd-0df5-47ff-b7a1-abf90df1fbe2,6de7f6ce-2392-4d16-9a47-bc06cf502607
55 | XYZprinting,4176871a-d65c-48dc-a813-02e464209277,7ecd4430-1ef2-4262-b472-4a7b33a352a9
56 | Zortrax,f66c38a2-869c-4a91-969f-831544181477,cb678fe8-ebc3-4924-ba24-df4321a0bf44
57 | ZMorph,e2d0a401-61b7-4c6d-9a8e-f956e52eaa59,3bb41c49-7ebe-4eab-8ac7-bb5bcd686903
--------------------------------------------------------------------------------
/settings/MonopriceSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class Monoprice
9 | {
10 | public const string UUID = "860432eb-dec6-4b20-8f97-3643a50daf1d";
11 |
12 | public enum Models {
13 | Unknown = 0,
14 | MP_Select_Mini_V2 = 1
15 | };
16 |
17 | public const string UUID_Unknown = "409e843b-c1d0-45fc-82d1-d7cc5635b8ee";
18 | public const string UUID_MP_Select_Mini_V2 = "4a498843-9080-4c97-aa82-b587f415ab1f";
19 | }
20 |
21 |
22 | public class MonopriceSettings : GenericRepRapSettings
23 | {
24 | public Monoprice.Models ModelEnum;
25 |
26 | public override AssemblerFactoryF AssemblerType() {
27 | return RepRapAssembler.Factory;
28 | }
29 |
30 |
31 | public MonopriceSettings(Monoprice.Models model) {
32 | ModelEnum = model;
33 |
34 | if (model == Monoprice.Models.MP_Select_Mini_V2)
35 | configure_MP_Select_Mini_V2();
36 | else
37 | configure_unknown();
38 | }
39 |
40 | public override T CloneAs() {
41 | MonopriceSettings copy = new MonopriceSettings(this.ModelEnum);
42 | this.CopyFieldsTo(copy);
43 | return copy as T;
44 | }
45 |
46 | public static IEnumerable EnumerateDefaults()
47 | {
48 | yield return new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2);
49 | yield return new MonopriceSettings(Monoprice.Models.Unknown);
50 | }
51 |
52 |
53 |
54 | void configure_MP_Select_Mini_V2()
55 | {
56 | Machine.ManufacturerName = "Monoprice";
57 | Machine.ManufacturerUUID = Monoprice.UUID;
58 | Machine.ModelIdentifier = "MP Select Mini V2";
59 | Machine.ModelUUID = Monoprice.UUID_MP_Select_Mini_V2;
60 | Machine.Class = MachineClass.PlasticFFFPrinter;
61 | Machine.BedSizeXMM = 120;
62 | Machine.BedSizeYMM = 120;
63 | Machine.MaxHeightMM = 120;
64 | Machine.NozzleDiamMM = 0.4;
65 | Machine.FilamentDiamMM = 1.75;
66 |
67 | Machine.MaxExtruderTempC = 250;
68 | Machine.HasHeatedBed = true;
69 | Machine.MaxBedTempC = 60;
70 |
71 | Machine.MaxExtrudeSpeedMMM = 55 * 60;
72 | Machine.MaxTravelSpeedMMM = 150 * 60;
73 | Machine.MaxZTravelSpeedMMM = 100 * 60;
74 | Machine.MaxRetractSpeedMMM = 100 * 60;
75 | Machine.MinLayerHeightMM = 0.1;
76 | Machine.MaxLayerHeightMM = 0.3;
77 |
78 |
79 | LayerHeightMM = 0.2;
80 |
81 | ExtruderTempC = 200;
82 | HeatedBedTempC = 0;
83 |
84 | SolidFillNozzleDiamStepX = 1.0;
85 | RetractDistanceMM = 4.5;
86 |
87 | RetractSpeed = Machine.MaxRetractSpeedMMM;
88 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
89 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
90 | CarefulExtrudeSpeed = 20 * 60;
91 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
92 | OuterPerimeterSpeedX = 0.5;
93 | }
94 |
95 |
96 |
97 |
98 | void configure_unknown()
99 | {
100 | Machine.ManufacturerName = "Monoprice";
101 | Machine.ManufacturerUUID = Monoprice.UUID;
102 | Machine.ModelIdentifier = "(Unknown)";
103 | Machine.ModelUUID = Monoprice.UUID_Unknown;
104 | Machine.Class = MachineClass.PlasticFFFPrinter;
105 | Machine.BedSizeXMM = 100;
106 | Machine.BedSizeYMM = 100;
107 | Machine.MaxHeightMM = 100;
108 | Machine.NozzleDiamMM = 0.4;
109 | Machine.FilamentDiamMM = 1.75;
110 |
111 | Machine.MaxExtruderTempC = 230;
112 | Machine.HasHeatedBed = false;
113 | Machine.MaxBedTempC = 0;
114 |
115 | Machine.HasAutoBedLeveling = false;
116 | Machine.EnableAutoBedLeveling = false;
117 |
118 | Machine.MaxExtrudeSpeedMMM = 60 * 60;
119 | Machine.MaxTravelSpeedMMM = 80 * 60;
120 | Machine.MaxZTravelSpeedMMM = 23 * 60;
121 | Machine.MaxRetractSpeedMMM = 20 * 60;
122 | Machine.MinLayerHeightMM = 0.1;
123 | Machine.MaxLayerHeightMM = 0.3;
124 |
125 | LayerHeightMM = 0.2;
126 |
127 | ExtruderTempC = 200;
128 | HeatedBedTempC = 0;
129 |
130 | SolidFillNozzleDiamStepX = 1.0;
131 | RetractDistanceMM = 1.0;
132 |
133 | RetractSpeed = Machine.MaxRetractSpeedMMM;
134 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
135 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
136 | CarefulExtrudeSpeed = 20 * 60;
137 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
138 | OuterPerimeterSpeedX = 0.5;
139 | }
140 |
141 |
142 | }
143 |
144 | }
--------------------------------------------------------------------------------
/settings/FlashforgeSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class Flashforge
9 | {
10 | public const string UUID = "5974064e-8751-4048-a700-73a023add74f";
11 |
12 | public enum Models {
13 | Unknown,
14 | CreatorPro
15 | };
16 |
17 | public const string UUID_Unknown = "f387a3d4-ba39-4a60-9e68-93ce7af4d92a";
18 | public const string UUID_CreatorPro = "0dd884e1-9b19-436e-9558-e4cb5fb27f7d";
19 | }
20 |
21 |
22 | public class FlashforgeSettings : SingleMaterialFFFSettings, ISailfishSettings
23 | {
24 | public Flashforge.Models ModelEnum;
25 |
26 | public override AssemblerFactoryF AssemblerType() {
27 | return MakerbotAssembler.Factory;
28 | }
29 |
30 | public FlashforgeSettings(Flashforge.Models model = Flashforge.Models.CreatorPro) {
31 | ModelEnum = model;
32 |
33 | if (model == Flashforge.Models.CreatorPro)
34 | configure_CreatorPro();
35 | else
36 | configure_unknown();
37 |
38 | }
39 |
40 |
41 | public override T CloneAs() {
42 | FlashforgeSettings copy = new FlashforgeSettings(this.ModelEnum);
43 | this.CopyFieldsTo(copy);
44 | return copy as T;
45 | }
46 |
47 |
48 | public static IEnumerable EnumerateDefaults()
49 | {
50 | yield return new FlashforgeSettings(Flashforge.Models.CreatorPro);
51 | yield return new FlashforgeSettings(Flashforge.Models.Unknown);
52 | }
53 |
54 |
55 | public string GPXModelFlag {
56 | get {
57 | if (ModelEnum == Flashforge.Models.CreatorPro)
58 | return "-m fcp";
59 | else
60 | return "";
61 | }
62 | }
63 |
64 |
65 | void configure_CreatorPro()
66 | {
67 | Machine.ManufacturerName = "Flashforge";
68 | Machine.ManufacturerUUID = Flashforge.UUID;
69 | Machine.ModelIdentifier = "Creator Pro";
70 | Machine.ModelUUID = Flashforge.UUID_CreatorPro;
71 | Machine.Class = MachineClass.PlasticFFFPrinter;
72 | Machine.BedSizeXMM = 227;
73 | Machine.BedSizeYMM = 148;
74 | Machine.MaxHeightMM = 150;
75 | Machine.NozzleDiamMM = 0.4;
76 | Machine.FilamentDiamMM = 1.75;
77 |
78 | Machine.MaxExtruderTempC = 230;
79 | Machine.HasHeatedBed = true;
80 | Machine.MaxBedTempC = 105;
81 |
82 | Machine.MaxExtrudeSpeedMMM = 60 * 60;
83 | Machine.MaxTravelSpeedMMM = 80 * 60;
84 | Machine.MaxZTravelSpeedMMM = 23 * 60;
85 | Machine.MaxRetractSpeedMMM = 20 * 60;
86 | Machine.MinLayerHeightMM = 0.1;
87 | Machine.MaxLayerHeightMM = 0.3;
88 |
89 | LayerHeightMM = 0.2;
90 |
91 | ExtruderTempC = 230;
92 | HeatedBedTempC = 25;
93 |
94 | SolidFillNozzleDiamStepX = 1.0;
95 | RetractDistanceMM = 1.3;
96 |
97 | RetractSpeed = Machine.MaxRetractSpeedMMM;
98 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
99 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
100 | CarefulExtrudeSpeed = 30 * 60;
101 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
102 | OuterPerimeterSpeedX = 0.5;
103 | }
104 |
105 |
106 | void configure_unknown()
107 | {
108 | Machine.ManufacturerName = "Flashforge";
109 | Machine.ManufacturerUUID = Flashforge.UUID;
110 | Machine.ModelIdentifier = "(Unknown)";
111 | Machine.ModelUUID = Flashforge.UUID_Unknown;
112 | Machine.Class = MachineClass.PlasticFFFPrinter;
113 |
114 | Machine.BedSizeXMM = 100;
115 | Machine.BedSizeYMM = 100;
116 | Machine.MaxHeightMM = 130;
117 | Machine.NozzleDiamMM = 0.4;
118 | Machine.FilamentDiamMM = 1.75;
119 |
120 | Machine.MaxExtruderTempC = 230;
121 | Machine.HasHeatedBed = false;
122 | Machine.MaxBedTempC = 0;
123 |
124 | Machine.MaxExtrudeSpeedMMM = 60 * 60;
125 | Machine.MaxTravelSpeedMMM = 80 * 60;
126 | Machine.MaxZTravelSpeedMMM = 23 * 60;
127 | Machine.MaxRetractSpeedMMM = 20 * 60;
128 | Machine.MinLayerHeightMM = 0.1;
129 | Machine.MaxLayerHeightMM = 0.3;
130 |
131 | LayerHeightMM = 0.2;
132 |
133 | ExtruderTempC = 230;
134 | HeatedBedTempC = 0;
135 |
136 | SolidFillNozzleDiamStepX = 1.0;
137 | RetractDistanceMM = 1.3;
138 |
139 | RetractSpeed = Machine.MaxRetractSpeedMMM;
140 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
141 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
142 | CarefulExtrudeSpeed = 30 * 60;
143 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
144 | OuterPerimeterSpeedX = 0.5;
145 | }
146 |
147 | }
148 |
149 | }
--------------------------------------------------------------------------------
/settings/MakerbotSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class Makerbot
9 | {
10 | public const string UUID = "77b7ed08-dcc8-4c2e-a189-18aa549bf94b";
11 |
12 | public enum Models {
13 | Unknown,
14 | Replicator2
15 | };
16 |
17 | public const string UUID_Unknown = "625aa5dc-8e9d-4240-86ff-8bc369cd5124";
18 | public const string UUID_Replicator2 = "a1c13f61-1ae6-4b1a-9c8c-18b2170e82b1";
19 | }
20 |
21 |
22 |
23 |
24 | public interface ISailfishSettings
25 | {
26 | string GPXModelFlag { get; }
27 | }
28 |
29 |
30 |
31 | public class MakerbotSettings : SingleMaterialFFFSettings, ISailfishSettings
32 | {
33 | public Makerbot.Models ModelEnum;
34 |
35 | public override AssemblerFactoryF AssemblerType() {
36 | return MakerbotAssembler.Factory;
37 | }
38 |
39 | public MakerbotSettings(Makerbot.Models model = Makerbot.Models.Replicator2) {
40 | ModelEnum = model;
41 |
42 | if (model == Makerbot.Models.Replicator2)
43 | configure_Replicator_2();
44 | else
45 | configure_unknown();
46 |
47 | }
48 |
49 |
50 | public override T CloneAs() {
51 | MakerbotSettings copy = new MakerbotSettings(this.ModelEnum);
52 | this.CopyFieldsTo(copy);
53 | return copy as T;
54 | }
55 |
56 |
57 | public static IEnumerable EnumerateDefaults()
58 | {
59 | yield return new MakerbotSettings(Makerbot.Models.Replicator2);
60 | yield return new MakerbotSettings(Makerbot.Models.Unknown);
61 | }
62 |
63 |
64 |
65 | public string GPXModelFlag {
66 | get {
67 | if (ModelEnum == Makerbot.Models.Replicator2)
68 | return "-m r2";
69 | else
70 | return "";
71 | }
72 | }
73 |
74 |
75 |
76 | void configure_Replicator_2()
77 | {
78 | Machine.ManufacturerName = "Makerbot";
79 | Machine.ManufacturerUUID = Makerbot.UUID;
80 | Machine.ModelIdentifier = "Replicator 2";
81 | Machine.ModelUUID = Makerbot.UUID_Replicator2;
82 | Machine.Class = MachineClass.PlasticFFFPrinter;
83 | Machine.BedSizeXMM = 285;
84 | Machine.BedSizeYMM = 153;
85 | Machine.MaxHeightMM = 155;
86 | Machine.NozzleDiamMM = 0.4;
87 | Machine.FilamentDiamMM = 1.75;
88 |
89 | Machine.MaxExtruderTempC = 230;
90 | Machine.HasHeatedBed = false;
91 | Machine.MaxBedTempC = 0;
92 |
93 | Machine.MaxExtrudeSpeedMMM = 90 * 60;
94 | Machine.MaxTravelSpeedMMM = 150 * 60;
95 | Machine.MaxZTravelSpeedMMM = 23 * 60;
96 | Machine.MaxRetractSpeedMMM = 25 * 60;
97 | Machine.MinLayerHeightMM = 0.1;
98 | Machine.MaxLayerHeightMM = 0.3;
99 |
100 |
101 | LayerHeightMM = 0.2;
102 |
103 | ExtruderTempC = 230;
104 | HeatedBedTempC = 0;
105 |
106 | SolidFillNozzleDiamStepX = 1.0;
107 | RetractDistanceMM = 1.3;
108 |
109 | RetractSpeed = Machine.MaxRetractSpeedMMM;
110 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
111 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
112 | CarefulExtrudeSpeed = 30 * 60;
113 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
114 | OuterPerimeterSpeedX = 0.5;
115 | }
116 |
117 |
118 | void configure_unknown()
119 | {
120 | Machine.ManufacturerName = "Makerbot";
121 | Machine.ManufacturerUUID = Makerbot.UUID;
122 | Machine.ModelIdentifier = "(Unknown)";
123 | Machine.ModelUUID = Makerbot.UUID_Unknown;
124 | Machine.Class = MachineClass.PlasticFFFPrinter;
125 |
126 | Machine.BedSizeXMM = 100;
127 | Machine.BedSizeYMM = 100;
128 | Machine.MaxHeightMM = 130;
129 | Machine.NozzleDiamMM = 0.4;
130 | Machine.FilamentDiamMM = 1.75;
131 |
132 | Machine.MaxExtruderTempC = 230;
133 | Machine.HasHeatedBed = false;
134 | Machine.MaxBedTempC = 0;
135 | Machine.MaxExtrudeSpeedMMM = 90 * 60;
136 | Machine.MaxTravelSpeedMMM = 150 * 60;
137 | Machine.MaxZTravelSpeedMMM = 23 * 60;
138 | Machine.MaxRetractSpeedMMM = 25 * 60;
139 | Machine.MinLayerHeightMM = 0.1;
140 | Machine.MaxLayerHeightMM = 0.3;
141 |
142 |
143 | LayerHeightMM = 0.2;
144 |
145 | ExtruderTempC = 230;
146 | HeatedBedTempC = 0;
147 |
148 | SolidFillNozzleDiamStepX = 1.0;
149 | RetractDistanceMM = 1.3;
150 |
151 | RetractSpeed = Machine.MaxRetractSpeedMMM;
152 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
153 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
154 | CarefulExtrudeSpeed = 30 * 60;
155 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
156 | OuterPerimeterSpeedX = 0.5;
157 | }
158 |
159 | }
160 |
161 | }
--------------------------------------------------------------------------------
/settings/PrintrbotSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class Printrbot
9 | {
10 | public const string UUID = "10dd0db9-df41-4b3e-8b73-d345c408b5ff";
11 |
12 | public enum Models {
13 | Unknown = 0,
14 | Plus = 1
15 | };
16 |
17 | public const string UUID_Unknown = "9a4cc498-376a-4780-956c-d0e145751868";
18 | public const string UUID_Plus = "1c868178-5aa2-47c3-9a8c-6f86ef1d1ff6";
19 | }
20 |
21 |
22 | public class PrintrbotSettings : GenericRepRapSettings
23 | {
24 | public Printrbot.Models ModelEnum;
25 |
26 | public override AssemblerFactoryF AssemblerType() {
27 | return MakePrintrbotAssembler;
28 | }
29 |
30 |
31 | public PrintrbotSettings(Printrbot.Models model) {
32 | ModelEnum = model;
33 |
34 | if (model == Printrbot.Models.Plus)
35 | configure_Plus();
36 | else
37 | configure_unknown();
38 | }
39 |
40 | public override T CloneAs() {
41 | PrintrbotSettings copy = new PrintrbotSettings(this.ModelEnum);
42 | this.CopyFieldsTo(copy);
43 | return copy as T;
44 | }
45 |
46 |
47 | public static IEnumerable EnumerateDefaults()
48 | {
49 | yield return new PrintrbotSettings(Printrbot.Models.Plus);
50 | yield return new PrintrbotSettings(Printrbot.Models.Unknown);
51 | }
52 |
53 |
54 |
55 | void configure_Plus()
56 | {
57 | Machine.ManufacturerName = "Printrbot";
58 | Machine.ManufacturerUUID = Printrbot.UUID;
59 | Machine.ModelIdentifier = "Plus";
60 | Machine.ModelUUID = Printrbot.UUID_Plus;
61 | Machine.Class = MachineClass.PlasticFFFPrinter;
62 | Machine.BedSizeXMM = 250;
63 | Machine.BedSizeYMM = 250;
64 | Machine.MaxHeightMM = 250;
65 | Machine.NozzleDiamMM = 0.4;
66 | Machine.FilamentDiamMM = 1.75;
67 |
68 | Machine.MaxExtruderTempC = 250;
69 | Machine.HasHeatedBed = true;
70 | Machine.MaxBedTempC = 80;
71 |
72 | Machine.MaxExtrudeSpeedMMM = 80 * 60;
73 | Machine.MaxTravelSpeedMMM = 120 * 60;
74 | Machine.MaxZTravelSpeedMMM = 100 * 60;
75 | Machine.MaxRetractSpeedMMM = 45 * 60;
76 | Machine.MinLayerHeightMM = 0.05;
77 | Machine.MaxLayerHeightMM = 0.3;
78 |
79 |
80 | LayerHeightMM = 0.2;
81 |
82 | ExtruderTempC = 200;
83 | HeatedBedTempC = 0;
84 |
85 | SolidFillNozzleDiamStepX = 1.0;
86 | RetractDistanceMM = 0.7;
87 |
88 | RetractSpeed = Machine.MaxRetractSpeedMMM;
89 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
90 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
91 | CarefulExtrudeSpeed = 20 * 60;
92 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
93 | OuterPerimeterSpeedX = 0.5;
94 |
95 | // specific to printrbot
96 | Machine.HasAutoBedLeveling = true;
97 | Machine.EnableAutoBedLeveling = true;
98 | }
99 |
100 |
101 |
102 |
103 | void configure_unknown()
104 | {
105 | Machine.ManufacturerName = "Printrbot";
106 | Machine.ManufacturerUUID = Printrbot.UUID;
107 | Machine.ModelIdentifier = "(Unknown)";
108 | Machine.ModelUUID = Printrbot.UUID_Unknown;
109 | Machine.Class = MachineClass.PlasticFFFPrinter;
110 | Machine.BedSizeXMM = 100;
111 | Machine.BedSizeYMM = 100;
112 | Machine.MaxHeightMM = 100;
113 | Machine.NozzleDiamMM = 0.4;
114 | Machine.FilamentDiamMM = 1.75;
115 |
116 | Machine.MaxExtruderTempC = 230;
117 | Machine.HasHeatedBed = false;
118 | Machine.MaxBedTempC = 0;
119 |
120 | Machine.HasAutoBedLeveling = false;
121 | Machine.EnableAutoBedLeveling = false;
122 |
123 | Machine.MaxExtrudeSpeedMMM = 60 * 60;
124 | Machine.MaxTravelSpeedMMM = 80 * 60;
125 | Machine.MaxZTravelSpeedMMM = 23 * 60;
126 | Machine.MaxRetractSpeedMMM = 20 * 60;
127 | Machine.MinLayerHeightMM = 0.1;
128 | Machine.MaxLayerHeightMM = 0.3;
129 |
130 | LayerHeightMM = 0.2;
131 |
132 | ExtruderTempC = 200;
133 | HeatedBedTempC = 0;
134 |
135 | SolidFillNozzleDiamStepX = 1.0;
136 | RetractDistanceMM = 1.0;
137 |
138 | RetractSpeed = Machine.MaxRetractSpeedMMM;
139 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
140 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
141 | CarefulExtrudeSpeed = 20 * 60;
142 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
143 | OuterPerimeterSpeedX = 0.5;
144 | }
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | public BaseDepositionAssembler MakePrintrbotAssembler(
153 | GCodeBuilder builder, SingleMaterialFFFSettings settings)
154 | {
155 | var asm = new RepRapAssembler(builder, settings);
156 | asm.HeaderCustomizerF = HeaderCustomF;
157 | return asm;
158 | }
159 |
160 | protected void HeaderCustomF(RepRapAssembler.HeaderState state, GCodeBuilder Builder)
161 | {
162 | if (state == RepRapAssembler.HeaderState.BeforePrime) {
163 | if ( Machine.HasAutoBedLeveling && Machine.EnableAutoBedLeveling )
164 | Builder.BeginGLine(29, "auto-level bed");
165 | }
166 | }
167 |
168 | }
169 |
170 | }
--------------------------------------------------------------------------------
/interpreters/ThreeAxisCNCInterpreter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 | ///
10 | /// Basic 3-axis CNC interpreter
11 | ///
12 | public class ThreeAxisCNCInterpreter : IGCodeInterpreter
13 | {
14 | IGCodeListener listener = null;
15 |
16 | Dictionary> GCodeMap = new Dictionary>();
17 | Dictionary> MCodeMap = new Dictionary>();
18 |
19 | bool UseRelativePosition = false;
20 |
21 |
22 | Vector3d CurPosition = Vector3d.Zero;
23 |
24 | bool in_travel = false;
25 | bool in_cut = false;
26 |
27 | public ThreeAxisCNCInterpreter() {
28 | build_maps();
29 | }
30 |
31 | public virtual void AddListener(IGCodeListener listener)
32 | {
33 | if (this.listener != null)
34 | throw new Exception("Only one listener supported!");
35 | this.listener = listener;
36 | }
37 |
38 |
39 | public virtual void Interpret(GCodeFile file, InterpretArgs args)
40 | {
41 | IEnumerable lines_enum =
42 | (args.HasTypeFilter) ? file.AllLines() : file.AllLinesOfType(args.eTypeFilter);
43 |
44 | listener.Begin();
45 |
46 | CurPosition = Vector3d.Zero;
47 |
48 | foreach(GCodeLine line in lines_enum) {
49 | Action parseF;
50 | if (line.type == GCodeLine.LType.GCode) {
51 | if (GCodeMap.TryGetValue(line.code, out parseF))
52 | parseF(line);
53 | } else if (line.type == GCodeLine.LType.MCode) {
54 | if (MCodeMap.TryGetValue(line.code, out parseF))
55 | parseF(line);
56 | }
57 | }
58 |
59 | listener.End();
60 | }
61 |
62 |
63 |
64 |
65 | public virtual IEnumerable InterpretInteractive(GCodeFile file, InterpretArgs args)
66 | {
67 | IEnumerable lines_enum =
68 | (args.HasTypeFilter) ? file.AllLinesOfType(args.eTypeFilter) : file.AllLines();
69 |
70 | listener.Begin();
71 |
72 | CurPosition = Vector3d.Zero;
73 |
74 | foreach (GCodeLine line in lines_enum) {
75 | if (line.type == GCodeLine.LType.GCode) {
76 | Action parseF;
77 | if (GCodeMap.TryGetValue(line.code, out parseF)) {
78 | parseF(line);
79 | yield return true;
80 | }
81 | }
82 | }
83 |
84 | listener.End();
85 |
86 | yield return false;
87 | }
88 |
89 |
90 |
91 | void emit_linear(GCodeLine line)
92 | {
93 | Debug.Assert(line.code == 0 || line.code == 1);
94 |
95 | double x = GCodeUtil.UnspecifiedValue,
96 | y = GCodeUtil.UnspecifiedValue,
97 | z = GCodeUtil.UnspecifiedValue;
98 | bool found_x = GCodeUtil.TryFindParamNum(line.parameters, "X", ref x);
99 | bool found_y = GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y);
100 | bool found_z = GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z);
101 | Vector3d newPos = (UseRelativePosition) ? Vector3d.Zero : CurPosition;
102 | if ( found_x )
103 | newPos.x = x;
104 | if ( found_y )
105 | newPos.y = y;
106 | if ( found_z )
107 | newPos.z = z;
108 | if (UseRelativePosition)
109 | CurPosition += newPos;
110 | else
111 | CurPosition = newPos;
112 |
113 | // F is feed rate (this changes?)
114 | double f = 0;
115 | bool haveF = GCodeUtil.TryFindParamNum(line.parameters, "F", ref f);
116 |
117 | LinearMoveData move = new LinearMoveData(
118 | newPos,
119 | (haveF) ? f : GCodeUtil.UnspecifiedValue );
120 |
121 | bool is_travel = (line.code == 0);
122 |
123 | if (is_travel) {
124 | if (in_travel == false) {
125 | listener.BeginTravel();
126 | in_travel = true;
127 | in_cut = false;
128 | }
129 | } else {
130 | if ( in_cut == false) {
131 | listener.BeginCut();
132 | in_travel = false;
133 | in_cut = true;
134 | }
135 | }
136 |
137 | move.source = line;
138 | Debug.Assert(in_travel || in_cut);
139 | listener.LinearMoveToAbsolute3d(move);
140 | }
141 |
142 |
143 |
144 | // G92 - Position register: Set the specified axes positions to the given position
145 | // Sets the position of the state machine and the bot. NB: There are two methods of forming the G92 command:
146 | void set_position(GCodeLine line)
147 | {
148 | double x = 0, y = 0, z = 0;
149 | if ( GCodeUtil.TryFindParamNum(line.parameters, "X", ref x ) ) {
150 | CurPosition.x = x;
151 | }
152 | if ( GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y ) ) {
153 | CurPosition.y = y;
154 | }
155 | if ( GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z ) ) {
156 | CurPosition.z = z;
157 | }
158 | }
159 |
160 |
161 | // G90
162 | void set_absolute_positioning(GCodeLine line) {
163 | UseRelativePosition = false;
164 | }
165 | // G91
166 | void set_relative_positioning(GCodeLine line) {
167 | UseRelativePosition = true;
168 | }
169 |
170 |
171 |
172 |
173 | void build_maps()
174 | {
175 | // G0 = rapid move
176 | GCodeMap[0] = emit_linear;
177 |
178 | // G1 = linear move
179 | GCodeMap[1] = emit_linear;
180 |
181 | // G4 = CCW circular
182 | //GCodeMap[4] = emit_ccw_arc;
183 | //GCodeMap[5] = emit_cw_arc;
184 |
185 | GCodeMap[90] = set_absolute_positioning; // http://reprap.org/wiki/G-code#G90:_Set_to_Absolute_Positioning
186 | GCodeMap[91] = set_relative_positioning; // http://reprap.org/wiki/G-code#G91:_Set_to_Relative_Positioning
187 | GCodeMap[92] = set_position; // http://reprap.org/wiki/G-code#G92:_Set_Position
188 | }
189 |
190 |
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/assemblers/RepRapAssembler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 | using gs;
7 |
8 | namespace gs
9 | {
10 |
11 | public class RepRapAssembler : BaseDepositionAssembler
12 | {
13 | public static BaseDepositionAssembler Factory(GCodeBuilder builder, SingleMaterialFFFSettings settings) {
14 | return new RepRapAssembler(builder, settings);
15 | }
16 |
17 |
18 | public SingleMaterialFFFSettings Settings;
19 |
20 |
21 | public RepRapAssembler(GCodeBuilder useBuilder, SingleMaterialFFFSettings settings) : base(useBuilder, settings.Machine)
22 | {
23 | Settings = settings;
24 |
25 | OmitDuplicateZ = true;
26 | OmitDuplicateF = true;
27 | OmitDuplicateE = true;
28 |
29 | HomeSequenceF = StandardHomeSequence;
30 | }
31 |
32 |
33 | //public override void BeginRetract(Vector3d pos, double feedRate, double extrudeDist, string comment = null) {
34 | // base.BeginRetract(pos, feedRate, extrudeDist, comment);
35 | //}
36 |
37 | //public override void EndRetract(Vector3d pos, double feedRate, double extrudeDist = -9999, string comment = null) {
38 | // base.EndRetract(pos, feedRate, extrudeDist, comment);
39 | //}
40 |
41 |
42 | public override void UpdateProgress(int i) {
43 | // not supported on reprap?
44 | //Builder.BeginMLine(73).AppendI("P",i);
45 | }
46 |
47 | public override void ShowMessage(string s)
48 | {
49 | Builder.BeginMLine(117).AppendL(s);
50 | }
51 |
52 | public override void EnableFan() {
53 | int fan_speed = (int)(Settings.FanSpeedX * 255.0);
54 | Builder.BeginMLine(106, "fan on").AppendI("S", fan_speed);
55 | }
56 | public override void DisableFan() {
57 | Builder.BeginMLine(107, "fan off");
58 | }
59 |
60 |
61 | ///
62 | /// Replace this to run your own home sequence
63 | ///
64 | public Action HomeSequenceF;
65 |
66 |
67 | public enum HeaderState
68 | {
69 | AfterComments,
70 | AfterTemperature,
71 | BeforeHome,
72 | BeforePrime
73 | };
74 | public Action HeaderCustomizerF = (state, builder) => { };
75 |
76 |
77 |
78 |
79 | public override void AppendHeader() {
80 | AppendHeader_StandardRepRap();
81 | }
82 | void AppendHeader_StandardRepRap() {
83 |
84 | base.AddStandardHeader(Settings);
85 |
86 | DisableFan();
87 |
88 | HeaderCustomizerF(HeaderState.AfterComments, Builder);
89 |
90 | /*
91 | * Configure temperatures
92 | */
93 |
94 | // do this first so it happens while bed heats
95 | SetExtruderTargetTemp(Settings.ExtruderTempC);
96 |
97 | // M190
98 | if (Settings.Machine.HasHeatedBed) {
99 | if (Settings.HeatedBedTempC > 0)
100 | SetBedTargetTempAndWait(Settings.HeatedBedTempC);
101 | else
102 | SetBedTargetTemp(0, "disable heated bed");
103 | }
104 |
105 | // M109
106 | SetExtruderTargetTempAndWait(Settings.ExtruderTempC);
107 |
108 |
109 | HeaderCustomizerF(HeaderState.AfterTemperature, Builder);
110 |
111 | Builder.BeginGLine(21, "units=mm");
112 | Builder.BeginGLine(90, "absolute positions");
113 | Builder.BeginMLine(82, "absolute extruder position");
114 |
115 | HeaderCustomizerF(HeaderState.BeforeHome, Builder);
116 |
117 | HomeSequenceF(Builder);
118 |
119 | currentPos = Vector3d.Zero;
120 |
121 | HeaderCustomizerF(HeaderState.BeforePrime, Builder);
122 |
123 | base.AddPrimeLine(Settings);
124 |
125 | // [RMS] this does not extrude very much and does not seem to work?
126 | //Builder.BeginGLine(1, "move platform down").AppendF("Z", 15).AppendI("F", 9000);
127 | //currentPos.z = 15;
128 | //Builder.BeginGLine(92, "reset extruded length").AppendI("E", 0);
129 | //extruderA = 0;
130 | //Builder.BeginGLine(1, "extrude blob").AppendI("F", 200).AppendI("E", 3);
131 | //Builder.BeginGLine(92, "reset extruded length again").AppendI("E", 0);
132 | //extruderA = 0;
133 | //Builder.BeginGLine(1, "reset speed").AppendI("F", 9000);
134 |
135 | // move to z=0
136 | BeginTravel();
137 | AppendMoveTo(new Vector3d(NozzlePosition.x,NozzlePosition.y,0), Settings.ZTravelSpeed, "reset z");
138 | EndTravel();
139 |
140 | ShowMessage("Print Started");
141 |
142 | in_retract = false;
143 | in_travel = false;
144 |
145 | EnableFan();
146 | UpdateProgress(0);
147 | }
148 |
149 |
150 |
151 |
152 | public override void AppendFooter() {
153 | AppendFooter_StandardRepRap();
154 | }
155 | void AppendFooter_StandardRepRap() {
156 |
157 | UpdateProgress(100);
158 |
159 | Builder.AddCommentLine("End of print");
160 | ShowMessage("Done!");
161 |
162 | DisableFan();
163 | SetExtruderTargetTemp(0, "extruder off");
164 | SetBedTargetTemp(0, "bed off");
165 |
166 | BeginRetractRelativeDist(currentPos, 300, -1, "final retract");
167 |
168 | Vector3d zup = currentPos;
169 | zup.z = Math.Min(Settings.Machine.MaxHeightMM, zup.z + 50);
170 | AppendMoveToE(zup, 9000, ExtruderA - 5.0, "move up and retract");
171 |
172 | Builder.BeginGLine(28, "home x/y").AppendI("X", 0).AppendI("Y", 0);
173 | currentPos.x = currentPos.y = 0;
174 |
175 | Builder.BeginMLine(84, "turn off steppers");
176 |
177 | Builder.EndLine(); // need to force this
178 | }
179 |
180 |
181 |
182 |
183 | public virtual void StandardHomeSequence(GCodeBuilder builder)
184 | {
185 | Builder.BeginGLine(28, "home x/y").AppendI("X", 0).AppendI("Y", 0);
186 | Builder.BeginGLine(28, "home z").AppendI("Z", 0);
187 | }
188 |
189 |
190 | }
191 |
192 |
193 | }
--------------------------------------------------------------------------------
/settings/PrusaSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using g3;
5 |
6 | namespace gs.info
7 | {
8 | public static class Prusa
9 | {
10 | public const string UUID = "4530287d-cd23-416c-b74b-4876c385750a";
11 |
12 | public enum Models {
13 | Unknown = 0,
14 | i3_MK3 = 1
15 | };
16 |
17 | public const string UUID_Unknown = "b7498970-b847-4a24-8e5c-2e7c0c4d417f";
18 | public const string UUID_I3_MK3 = "fc09f99c-aee0-45e9-bca3-3e088ccb0b55";
19 | }
20 |
21 |
22 | public class PrusaSettings : GenericRepRapSettings
23 | {
24 | public Prusa.Models ModelEnum;
25 |
26 | public override AssemblerFactoryF AssemblerType() {
27 | return MakePrusaAssembler;
28 | }
29 |
30 |
31 | public PrusaSettings(Prusa.Models model) {
32 | ModelEnum = model;
33 |
34 | if (model == Prusa.Models.i3_MK3)
35 | configure_i3_MK3();
36 | else
37 | configure_unknown();
38 | }
39 |
40 | public override T CloneAs() {
41 | PrusaSettings copy = new PrusaSettings(this.ModelEnum);
42 | this.CopyFieldsTo(copy);
43 | return copy as T;
44 | }
45 |
46 |
47 | public static IEnumerable EnumerateDefaults()
48 | {
49 | yield return new PrusaSettings(Prusa.Models.i3_MK3);
50 | yield return new PrusaSettings(Prusa.Models.Unknown);
51 | }
52 |
53 |
54 | void configure_i3_MK3()
55 | {
56 | Machine.ManufacturerName = "Prusa";
57 | Machine.ManufacturerUUID = Prusa.UUID;
58 | Machine.ModelIdentifier = "i3 MK3";
59 | Machine.ModelUUID = Prusa.UUID_I3_MK3;
60 | Machine.Class = MachineClass.PlasticFFFPrinter;
61 | Machine.BedSizeXMM = 250;
62 | Machine.BedSizeYMM = 210;
63 | Machine.MaxHeightMM = 200;
64 | Machine.NozzleDiamMM = 0.4;
65 | Machine.FilamentDiamMM = 1.75;
66 |
67 | Machine.MaxExtruderTempC = 300;
68 | Machine.HasHeatedBed = true;
69 | Machine.MaxBedTempC = 120;
70 |
71 | Machine.HasAutoBedLeveling = true;
72 | Machine.EnableAutoBedLeveling = true;
73 |
74 | Machine.MaxExtrudeSpeedMMM = 80 * 60;
75 | Machine.MaxTravelSpeedMMM = 120 * 60;
76 | Machine.MaxZTravelSpeedMMM = 250 * 60;
77 | Machine.MaxRetractSpeedMMM = 35 * 60;
78 | Machine.MinLayerHeightMM = 0.05;
79 | Machine.MaxLayerHeightMM = 0.35;
80 |
81 | LayerHeightMM = 0.2;
82 |
83 | ExtruderTempC = 200;
84 | HeatedBedTempC = 60;
85 |
86 | SolidFillNozzleDiamStepX = 1.0;
87 | RetractDistanceMM = 0.7;
88 |
89 | RetractSpeed = Machine.MaxRetractSpeedMMM;
90 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
91 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
92 | CarefulExtrudeSpeed = 20 * 60;
93 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
94 | OuterPerimeterSpeedX = 0.5;
95 | }
96 |
97 |
98 |
99 |
100 | void configure_unknown()
101 | {
102 | Machine.ManufacturerName = "Prusa";
103 | Machine.ManufacturerUUID = Prusa.UUID;
104 | Machine.ModelIdentifier = "(Unknown)";
105 | Machine.ModelUUID = Prusa.UUID_Unknown;
106 | Machine.Class = MachineClass.PlasticFFFPrinter;
107 | Machine.BedSizeXMM = 100;
108 | Machine.BedSizeYMM = 100;
109 | Machine.MaxHeightMM = 100;
110 | Machine.NozzleDiamMM = 0.4;
111 | Machine.FilamentDiamMM = 1.75;
112 |
113 | Machine.MaxExtruderTempC = 230;
114 | Machine.HasHeatedBed = false;
115 | Machine.MaxBedTempC = 0;
116 |
117 | Machine.HasAutoBedLeveling = false;
118 | Machine.EnableAutoBedLeveling = false;
119 |
120 | Machine.MaxExtrudeSpeedMMM = 60 * 60;
121 | Machine.MaxTravelSpeedMMM = 80 * 60;
122 | Machine.MaxZTravelSpeedMMM = 23 * 60;
123 | Machine.MaxRetractSpeedMMM = 20 * 60;
124 | Machine.MinLayerHeightMM = 0.1;
125 | Machine.MaxLayerHeightMM = 0.3;
126 |
127 | LayerHeightMM = 0.2;
128 |
129 | ExtruderTempC = 200;
130 | HeatedBedTempC = 0;
131 |
132 | SolidFillNozzleDiamStepX = 1.0;
133 | RetractDistanceMM = 1.0;
134 |
135 | RetractSpeed = Machine.MaxRetractSpeedMMM;
136 | ZTravelSpeed = Machine.MaxZTravelSpeedMMM;
137 | RapidTravelSpeed = Machine.MaxTravelSpeedMMM;
138 | CarefulExtrudeSpeed = 20 * 60;
139 | RapidExtrudeSpeed = Machine.MaxExtrudeSpeedMMM;
140 | OuterPerimeterSpeedX = 0.5;
141 | }
142 |
143 |
144 |
145 |
146 |
147 | public BaseDepositionAssembler MakePrusaAssembler(
148 | GCodeBuilder builder, SingleMaterialFFFSettings settings)
149 | {
150 | var asm = new RepRapAssembler(builder, settings);
151 | asm.HomeSequenceF = this.HomeSequence;
152 | asm.HeaderCustomizerF = HeaderCustomF;
153 | asm.TravelGCode = 1;
154 | return asm;
155 | }
156 |
157 |
158 | protected virtual void HomeSequence(GCodeBuilder builder)
159 | {
160 | if (Machine.HasAutoBedLeveling && Machine.EnableAutoBedLeveling) {
161 | builder.BeginGLine(28).AppendL("W").AppendComment("home all without bed level");
162 | builder.BeginGLine(80, "auto-level bed");
163 | } else {
164 | // standard home sequenece
165 | builder.BeginGLine(28, "home x/y").AppendI("X", 0).AppendI("Y", 0);
166 | builder.BeginGLine(28, "home z").AppendI("Z", 0);
167 | }
168 |
169 | }
170 |
171 |
172 | protected virtual void HeaderCustomF(RepRapAssembler.HeaderState state, GCodeBuilder Builder)
173 | {
174 | if (state == RepRapAssembler.HeaderState.AfterComments ) {
175 |
176 | if ( ModelEnum == Prusa.Models.i3_MK3 ) {
177 | Builder.BeginMLine(201)
178 | .AppendI("X",1000).AppendI("Y",1000).AppendI("Z",200).AppendI("E",5000)
179 | .AppendComment("Set maximum accelleration in mm/sec^2");
180 | Builder.BeginMLine(203)
181 | .AppendI("X", 200).AppendI("Y", 200).AppendI("Z", 12).AppendI("E", 120)
182 | .AppendComment("Set maximum feedrates in mm/sec");
183 | Builder.BeginMLine(204)
184 | .AppendI("S", 1250).AppendI("T", 1250)
185 | .AppendComment("Set acceleration for moves (S) and retract (T)");
186 | Builder.BeginMLine(205)
187 | .AppendF("X", 10).AppendF("Y", 10).AppendF("Z", 0.4).AppendF("E", 2.5)
188 | .AppendComment("Set jerk limits in mm/sec");
189 | Builder.BeginMLine(205)
190 | .AppendI("S", 0).AppendI("T", 0)
191 | .AppendComment("Set minimum extrude and travel feed rate in mm/sec");
192 | }
193 |
194 |
195 | }
196 | }
197 |
198 | }
199 |
200 | }
--------------------------------------------------------------------------------
/assemblers/MakerbotAssembler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 |
10 | public class MakerbotAssembler : BaseDepositionAssembler
11 | {
12 | public static BaseDepositionAssembler Factory(GCodeBuilder builder, SingleMaterialFFFSettings settings) {
13 | return new MakerbotAssembler(builder, settings);
14 | }
15 |
16 |
17 | public SingleMaterialFFFSettings Settings;
18 |
19 |
20 | public MakerbotAssembler(GCodeBuilder useBuilder, SingleMaterialFFFSettings settings) : base(useBuilder, settings.Machine)
21 | {
22 | Settings = settings as SingleMaterialFFFSettings;
23 |
24 | PositionBounds = new AxisAlignedBox2d(settings.Machine.BedSizeXMM, settings.Machine.BedSizeYMM);
25 | PositionBounds.Translate(-PositionBounds.Center);
26 |
27 | // [RMS] currently bed dimensions are hardcoded in header setup, and this trips bounds-checker.
28 | // So, disable this checking for now.
29 | EnableBoundsChecking = false;
30 |
31 | TravelGCode = 1;
32 | }
33 |
34 |
35 | public override void BeginRetract(Vector3d pos, double feedRate, double extrudeDist, string comment = null) {
36 | // [TODO] makerbot gcode disables fan here
37 | // disable fan for every tiny travel? seems pointless...
38 |
39 | base.BeginRetract(pos, feedRate, extrudeDist, comment);
40 |
41 | // [RMS] makerbot does this...but does it do anything??
42 | base.BeginTravel();
43 | AppendMoveTo(pos, 3000, "Retract 2?");
44 | base.EndTravel();
45 | }
46 |
47 | public override void EndRetract(Vector3d pos, double feedRate, double extrudeDist = -9999, string comment = null) {
48 | base.EndRetract(pos, feedRate, extrudeDist, comment);
49 |
50 | // [TODO] re-enable fan here
51 | }
52 |
53 |
54 |
55 |
56 | public override void UpdateProgress(int i) {
57 | Builder.BeginMLine(73).AppendI("P",i);
58 | }
59 |
60 |
61 | public override void EnableFan() {
62 | // makerbot-style firmware does not support fan speed?
63 | Builder.BeginMLine(126).AppendI("T",0);
64 | }
65 | public override void DisableFan() {
66 | Builder.BeginMLine(127).AppendI("T",0);
67 | }
68 |
69 | public override void ShowMessage(string s) {
70 | // do nothing (not available)
71 | }
72 |
73 |
74 |
75 |
76 | public override void AppendHeader() {
77 | AppendHeader_Replicator2();
78 | }
79 | void AppendHeader_Replicator2() {
80 |
81 | base.AddStandardHeader(Settings);
82 |
83 | Vector3d frontRight = new Vector3d(Settings.Machine.BedSizeXMM / 2, -Settings.Machine.BedSizeYMM / 2, 0);
84 | frontRight.x -= 10;
85 | frontRight.y += 5;
86 | Vector3d FrontLeft = frontRight; FrontLeft.x = -frontRight.x;
87 | //Vector3d BackRight = frontRight; BackRight.y = -frontRight.y;
88 |
89 | Builder.BeginMLine(136, "(enable build)");
90 |
91 | // reset build percentage
92 | UpdateProgress(0);
93 |
94 | // set target temperature. Do this before home because it will happen faster then.
95 | Builder.BeginMLine(135, "select tool 0")
96 | .AppendI("T", 0);
97 | Builder.BeginMLine(104, "set target tool temperature")
98 | .AppendI("S", Settings.ExtruderTempC).AppendI("T", 0);
99 | if (Settings.Machine.HasHeatedBed) {
100 | Builder.BeginMLine(140, "set heated bed temperature")
101 | .AppendI("S", Settings.HeatedBedTempC).AppendI("T", 0);
102 | }
103 |
104 | // homing
105 |
106 | Builder.BeginGLine(162, "(home XY axes maximum)")
107 | .AppendL("X").AppendL("Y").AppendI("F", 2000);
108 |
109 | Builder.BeginGLine(161, "(home Z axis minimum)")
110 | .AppendL("Z").AppendI("F", 900);
111 |
112 | Builder.BeginGLine(92, "(set Z to -5)").
113 | AppendI("X",0).AppendI("Y",0).AppendI("Z",-5).AppendI("A",0).AppendI("B",0);
114 | currentPos = new Vector3d(0, 0, -5);
115 | extruderA = 0;
116 |
117 | Builder.BeginGLine(1, "(move Z to '0')")
118 | .AppendI("Z", 0).AppendI("F", 900);
119 | currentPos.z = 0;
120 |
121 | Builder.BeginGLine(161, "(home Z axis minimum)")
122 | .AppendL("Z").AppendI("F", 100);
123 |
124 | Builder.BeginMLine(132, "(Recall stored home offsets for XYZAB axis)").
125 | AppendL("X").AppendL("Y").AppendL("Z").AppendL("A").AppendL("B");
126 |
127 | // [RMS] this line is not necessary
128 | //Builder.BeginGLine(92).
129 | // AppendF("X",BackRight.x).AppendF("Y",BackRight.y).AppendI("Z",0).AppendI("A",0).AppendI("B",0);
130 | //currentPos = new Vector3d(BackRight.x, BackRight.y, 0);
131 | //extruderA = 0;
132 |
133 | Builder.BeginGLine(1, "(move to waiting position)").
134 | AppendF("X",FrontLeft.x).AppendF("Y",FrontLeft.y).AppendI("Z",40).AppendI("F",3300);
135 | currentPos = new Vector3d(FrontLeft.x, FrontLeft.y, 40);
136 |
137 | Builder.BeginGLine(130, "(Lower stepper Vrefs while heating)").
138 | AppendI("X",20).AppendI("Y",20).AppendI("A",20).AppendI("B",20);
139 |
140 | if ( Settings.Machine.HasHeatedBed ) {
141 | Builder.BeginMLine(134, "wait for bed to heat")
142 | .AppendI("T", 0);
143 | }
144 |
145 | // wait to heat
146 | Builder.BeginMLine(133, "wait for tool to heat")
147 | .AppendI("T",0);
148 |
149 | Builder.BeginGLine(130, "(Set Stepper motor Vref to defaults)").
150 | AppendI("X",127).AppendI("Y",127).AppendI("A",127).AppendI("B",127);
151 |
152 | // prime
153 | base.AddPrimeLine(Settings);
154 |
155 | // this isn't necessary anymore...
156 | Builder.BeginGLine(92, "(Reset after prime)").AppendI("A", 0).AppendI("B", 0);
157 |
158 | // move to z=0
159 | Builder.BeginGLine(1).AppendI("Z",0).AppendI("F",1000);
160 | currentPos.z = 0;
161 |
162 | // move to front-left corner
163 | AppendMoveToE(FrontLeft.x, FrontLeft.y, 0, 1000, 0);
164 |
165 | in_retract = false;
166 | in_travel = false;
167 |
168 | EnableFan();
169 | UpdateProgress(0);
170 | }
171 |
172 |
173 |
174 |
175 |
176 | public override void AppendFooter() {
177 | AppendFooter_Replicator2();
178 | }
179 | void AppendFooter_Replicator2() {
180 | double MaxHeight = 155;
181 |
182 | Builder.AddCommentLine("End of print");
183 |
184 | // final retract
185 | if (InRetract == false) {
186 | BeginRetract(NozzlePosition, Settings.RetractSpeed,
187 | ExtruderA - Settings.RetractDistanceMM, "Final Retract");
188 | }
189 |
190 | //G1 X-9.119 Y10.721 Z0.200 F1500 A61.36007; Retract
191 |
192 | Builder.BeginMLine(127, "(Fan Off)").AppendI("T",0);
193 | Builder.BeginMLine(18, "(Turn off A and B Steppers)").AppendL("A").AppendL("B");
194 |
195 | // move bed to max height
196 | Builder.BeginGLine(1).AppendF("Z",MaxHeight).AppendI("F",900);
197 |
198 | // home steppers and turn off
199 | Builder.BeginGLine(162).AppendL("X").AppendL("Y").AppendI("F", 2000);
200 | Builder.BeginMLine(18,"(Turn off steppers)").AppendL("X").AppendL("Y").AppendL("Z");
201 |
202 | // set temp to 0
203 | Builder.BeginMLine(104, "set target tool temperature").AppendI("S",0).AppendI("T",0);
204 |
205 | if ( Settings.Machine.HasHeatedBed ) {
206 | Builder.BeginMLine(140, "set heated bed temperature")
207 | .AppendI("S", 0).AppendI("T", 0);
208 | }
209 |
210 | // set built-in status message
211 | Builder.BeginMLine(70, "// Cotangent //").AppendI("P",5);
212 |
213 | // skip song
214 | //Builder.BeginMLine(72).AppendI("P",1);
215 |
216 | UpdateProgress(100);
217 |
218 | Builder.BeginMLine(137,"(build end notification)");
219 |
220 | Builder.EndLine(); // need to force this
221 | }
222 |
223 | }
224 |
225 |
226 | }
--------------------------------------------------------------------------------
/interpreters/MakerbotInterpreter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using g3;
6 |
7 | namespace gs
8 | {
9 | // useful documents:
10 | // https://github.com/makerbot/s3g/blob/master/doc/GCodeProtocol.md
11 |
12 |
13 | ///
14 | /// Makerbot GCode interpreter.
15 | ///
16 | public class MakerbotInterpreter : IGCodeInterpreter
17 | {
18 | IGCodeListener listener = null;
19 |
20 | Dictionary> GCodeMap = new Dictionary>();
21 | Dictionary> MCodeMap = new Dictionary>();
22 |
23 |
24 | bool UseRelativePosition = false;
25 | bool UseRelativeExtruder = false;
26 |
27 |
28 | Vector3d CurPosition = Vector3d.Zero;
29 |
30 | double ExtrusionA = 0;
31 | double LastRetractA = 0;
32 | bool in_retract = false;
33 | bool in_travel = false;
34 | bool in_extrude = false;
35 |
36 | public MakerbotInterpreter() {
37 | build_maps();
38 | }
39 |
40 | public virtual void AddListener(IGCodeListener listener)
41 | {
42 | if (this.listener != null)
43 | throw new Exception("Only one listener supported!");
44 | this.listener = listener;
45 | }
46 |
47 |
48 | public virtual void Interpret(GCodeFile file, InterpretArgs args)
49 | {
50 | IEnumerable lines_enum =
51 | (args.HasTypeFilter) ? file.AllLines() : file.AllLinesOfType(args.eTypeFilter);
52 |
53 | listener.Begin();
54 |
55 | ExtrusionA = 0;
56 | CurPosition = Vector3d.Zero;
57 |
58 | foreach(GCodeLine line in lines_enum) {
59 | Action parseF;
60 | if (line.type == GCodeLine.LType.GCode) {
61 | if (GCodeMap.TryGetValue(line.code, out parseF))
62 | parseF(line);
63 | } else if (line.type == GCodeLine.LType.MCode) {
64 | if (MCodeMap.TryGetValue(line.code, out parseF))
65 | parseF(line);
66 | }
67 | }
68 |
69 | listener.End();
70 | }
71 |
72 |
73 |
74 |
75 | public virtual IEnumerable InterpretInteractive(GCodeFile file, InterpretArgs args)
76 | {
77 | IEnumerable lines_enum =
78 | (args.HasTypeFilter) ? file.AllLinesOfType(args.eTypeFilter) : file.AllLines();
79 |
80 | listener.Begin();
81 |
82 | ExtrusionA = 0;
83 | CurPosition = Vector3d.Zero;
84 |
85 | foreach (GCodeLine line in lines_enum) {
86 | if (line.type == GCodeLine.LType.GCode) {
87 | Action parseF;
88 | if (GCodeMap.TryGetValue(line.code, out parseF)) {
89 | parseF(line);
90 | yield return true;
91 | }
92 | }
93 | }
94 |
95 | listener.End();
96 |
97 | yield return false;
98 | }
99 |
100 |
101 |
102 | void emit_linear(GCodeLine line)
103 | {
104 | Debug.Assert(line.code == 0 || line.code == 1);
105 |
106 | double x = GCodeUtil.UnspecifiedValue,
107 | y = GCodeUtil.UnspecifiedValue,
108 | z = GCodeUtil.UnspecifiedValue;
109 | bool found_x = GCodeUtil.TryFindParamNum(line.parameters, "X", ref x);
110 | bool found_y = GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y);
111 | bool found_z = GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z);
112 | Vector3d newPos = (UseRelativePosition) ? Vector3d.Zero : CurPosition;
113 | if ( found_x )
114 | newPos.x = x;
115 | if ( found_y )
116 | newPos.y = y;
117 | if ( found_z )
118 | newPos.z = z;
119 | if (UseRelativePosition)
120 | CurPosition += newPos;
121 | else
122 | CurPosition = newPos;
123 |
124 | // F is feed rate (this changes?)
125 | double f = 0;
126 | bool haveF = GCodeUtil.TryFindParamNum(line.parameters, "F", ref f);
127 |
128 | // A is extrusion stepper. E is also "current" stepper.
129 | double a = 0;
130 | bool haveA = GCodeUtil.TryFindParamNum(line.parameters, "A", ref a);
131 | if ( haveA == false ) {
132 | haveA = GCodeUtil.TryFindParamNum(line.parameters, "E", ref a);
133 | }
134 | if (UseRelativeExtruder)
135 | a = ExtrusionA + a;
136 |
137 | LinearMoveData move = new LinearMoveData(
138 | newPos,
139 | (haveF) ? f : GCodeUtil.UnspecifiedValue,
140 | (haveA) ? GCodeUtil.Extrude(a) : GCodeUtil.UnspecifiedPosition );
141 |
142 | if ( haveA == false ) {
143 | // if we do not have extrusion, this is a travel move
144 | if (in_travel == false) {
145 | listener.BeginTravel();
146 | in_travel = true;
147 | in_extrude = false;
148 | }
149 |
150 | } else if (in_retract) {
151 | // if we are in retract, we stay in until we see forward movement
152 |
153 | Debug.Assert(in_travel);
154 | Debug.Assert(a <= LastRetractA+0.001);
155 | if ( MathUtil.EpsilonEqual(a, LastRetractA, 0.00001) ) {
156 | in_retract = false;
157 | listener.BeginDeposition();
158 | in_extrude = true;
159 | in_travel = false;
160 | ExtrusionA = a;
161 | }
162 |
163 | } else if ( a < ExtrusionA ) {
164 | // if extrusion moved backwards, we need to enter travel
165 |
166 | in_retract = true;
167 | LastRetractA = ExtrusionA;
168 | ExtrusionA = a;
169 | if (in_travel == false) {
170 | listener.BeginTravel();
171 | in_travel = true;
172 | in_extrude = false;
173 | }
174 | } else {
175 | // if we are in travel, we need to begin extruding
176 | if (in_travel) {
177 | listener.BeginDeposition();
178 | in_travel = false;
179 | in_extrude = true;
180 | }
181 | if (in_extrude == false) { // handle initialization cases
182 | listener.BeginDeposition();
183 | in_extrude = true;
184 | }
185 | ExtrusionA = a;
186 | }
187 |
188 | move.source = line;
189 | Debug.Assert(in_travel || in_extrude);
190 | listener.LinearMoveToAbsolute3d(move);
191 | }
192 |
193 |
194 |
195 | // G92 - Position register: Set the specified axes positions to the given position
196 | // Sets the position of the state machine and the bot. NB: There are two methods of forming the G92 command:
197 | void set_position(GCodeLine line)
198 | {
199 | double x = 0, y = 0, z = 0, a = 0;
200 | if ( GCodeUtil.TryFindParamNum(line.parameters, "X", ref x ) ) {
201 | CurPosition.x = x;
202 | }
203 | if ( GCodeUtil.TryFindParamNum(line.parameters, "Y", ref y ) ) {
204 | CurPosition.y = y;
205 | }
206 | if ( GCodeUtil.TryFindParamNum(line.parameters, "Z", ref z ) ) {
207 | CurPosition.z = z;
208 | }
209 | if ( GCodeUtil.TryFindParamNum(line.parameters, "A", ref a ) ) {
210 | ExtrusionA = a;
211 | listener.CustomCommand(
212 | (int)CustomListenerCommands.ResetExtruder, GCodeUtil.Extrude(a) );
213 | // reset our state
214 | in_travel = in_extrude = in_retract = false;
215 | }
216 |
217 | // E is "current" stepper (A for single extruder)
218 | double e = 0;
219 | if ( GCodeUtil.TryFindParamNum(line.parameters, "E", ref e ) ) {
220 | ExtrusionA = e;
221 | listener.CustomCommand(
222 | (int)CustomListenerCommands.ResetExtruder, GCodeUtil.Extrude(e) );
223 | // reset our state
224 | in_travel = in_extrude = in_retract = false;
225 | }
226 | }
227 |
228 |
229 | // G90
230 | void set_absolute_positioning(GCodeLine line) {
231 | UseRelativePosition = false;
232 | }
233 | // G91
234 | void set_relative_positioning(GCodeLine line) {
235 | UseRelativePosition = true;
236 |
237 | // [RMS] according to http://reprap.org/wiki/G-code#G91:_Set_to_Relative_Positioning,
238 | // this should only happen on some firmware...
239 | UseRelativeExtruder = true;
240 | }
241 |
242 |
243 | // M82
244 | void set_absolute_extruder(GCodeLine line) {
245 | UseRelativeExtruder = false;
246 | }
247 | // M83
248 | void set_relative_extruder(GCodeLine line) {
249 | UseRelativeExtruder = true;
250 | }
251 |
252 |
253 |
254 | void build_maps()
255 | {
256 | // G0 = rapid move
257 | GCodeMap[0] = emit_linear;
258 |
259 | // G1 = linear move
260 | GCodeMap[1] = emit_linear;
261 |
262 | // G4 = CCW circular
263 | //GCodeMap[4] = emit_ccw_arc;
264 | //GCodeMap[5] = emit_cw_arc;
265 |
266 | GCodeMap[90] = set_absolute_positioning; // http://reprap.org/wiki/G-code#G90:_Set_to_Absolute_Positioning
267 | GCodeMap[91] = set_relative_positioning; // http://reprap.org/wiki/G-code#G91:_Set_to_Relative_Positioning
268 | GCodeMap[92] = set_position; // http://reprap.org/wiki/G-code#G92:_Set_Position
269 |
270 |
271 | MCodeMap[82] = set_absolute_extruder; // http://reprap.org/wiki/G-code#M83:_Set_extruder_to_relative_mode
272 | MCodeMap[83] = set_relative_extruder; // http://reprap.org/wiki/G-code#M83:_Set_extruder_to_relative_mode
273 | }
274 |
275 |
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/assemblers/BaseMillingAssembler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 | using gs;
7 |
8 | namespace gs
9 | {
10 |
11 | public interface IMillingAssembler : IGCodeAssembler
12 | {
13 | }
14 |
15 |
16 | public delegate BaseMillingAssembler MillingAssemblerFactoryF(GCodeBuilder builder, SingleMaterialFFFSettings settings);
17 |
18 |
19 | ///
20 | /// Assembler translates high-level commands from Compiler (eg MoveTo, BeginRetract, etc)
21 | /// into GCode instructions, which it passes to GCodeBuilder instance.
22 | ///
23 | /// To do this, Assembler maintains state machine for things like current tool position
24 | ///
25 | /// TODO:
26 | /// - support relative mode
27 | ///
28 | ///
29 | public abstract class BaseMillingAssembler : IMillingAssembler
30 | {
31 | public GCodeBuilder Builder;
32 |
33 | ///
34 | /// To keep things simple, we use the absolute coordinates of the slice polygons
35 | /// at the higher levels. However the printer often operates in some other coordinate
36 | /// system, for example relative to front-left corner. PositionShift is added to all x/y
37 | /// coordinates before they are passed to the GCodeBuilder.
38 | ///
39 | public Vector2d PositionShift = Vector2d.Zero;
40 |
41 |
42 | ///
43 | /// check that all points lie within bounds
44 | ///
45 | public bool EnableBoundsChecking = true;
46 |
47 | ///
48 | /// if EnableBoundsChecking=true, will assert if we try to move outside these bounds
49 | ///
50 | public AxisAlignedBox2d PositionBounds = AxisAlignedBox2d.Infinite;
51 |
52 | public bool OmitDuplicateZ = false;
53 | public bool OmitDuplicateF = false;
54 |
55 | // threshold for omitting "duplicate" Z/F parameters
56 | public double MoveEpsilon = 0.00001;
57 |
58 | public BaseMillingAssembler(GCodeBuilder useBuilder, FFFMachineInfo machineInfo)
59 | {
60 | Builder = useBuilder;
61 | currentPos = Vector3d.Zero;
62 | currentFeed = 0;
63 | }
64 |
65 |
66 | /*
67 | * Subclasses must implement these
68 | */
69 |
70 | public abstract void AppendHeader();
71 | public abstract void AppendFooter();
72 | public abstract void UpdateProgress(int i);
73 | public abstract void ShowMessage(string s);
74 |
75 |
76 | /*
77 | * Position commands
78 | */
79 |
80 | protected Vector3d currentPos;
81 | public Vector3d ToolPosition {
82 | get { return currentPos; }
83 | }
84 |
85 | protected double currentFeed;
86 | public double FeedRate {
87 | get { return currentFeed; }
88 | }
89 |
90 |
91 | protected bool in_retract;
92 | public bool InRetract {
93 | get { return in_retract; }
94 | }
95 |
96 | protected bool in_travel;
97 | public bool InTravel {
98 | get { return in_travel; }
99 | }
100 |
101 | public bool InCut {
102 | get { return InTravel == false; }
103 | }
104 |
105 |
106 |
107 |
108 | // actually emit travel move gcode
109 | protected virtual void emit_travel(Vector3d toPos, double feedRate, string comment)
110 | {
111 | double write_x = toPos.x + PositionShift.x;
112 | double write_y = toPos.y + PositionShift.y;
113 |
114 | Builder.BeginGLine(0, comment).
115 | AppendF("X", write_x).AppendF("Y", write_y);
116 |
117 | if (OmitDuplicateZ == false || MathUtil.EpsilonEqual(currentPos.z, toPos.z, MoveEpsilon) == false) {
118 | Builder.AppendF("Z", toPos.z);
119 | }
120 | if (OmitDuplicateF == false || MathUtil.EpsilonEqual(currentFeed, feedRate, MoveEpsilon) == false) {
121 | Builder.AppendF("F", feedRate);
122 | }
123 |
124 | currentPos = toPos;
125 | currentFeed = feedRate;
126 | }
127 |
128 |
129 | // emit gcode for an cut move
130 | protected virtual void emit_cut(Vector3d toPos, double feedRate, string comment = null)
131 | {
132 | double write_x = toPos.x + PositionShift.x;
133 | double write_y = toPos.y + PositionShift.y;
134 | Builder.BeginGLine(1, comment).
135 | AppendF("X", write_x).AppendF("Y", write_y);
136 |
137 | if (OmitDuplicateZ == false || MathUtil.EpsilonEqual(toPos.z, currentPos.z, MoveEpsilon) == false) {
138 | Builder.AppendF("Z", toPos.z);
139 | }
140 | if (OmitDuplicateF == false || MathUtil.EpsilonEqual(feedRate, currentFeed, MoveEpsilon) == false) {
141 | Builder.AppendF("F", feedRate);
142 | }
143 |
144 | currentPos = toPos;
145 | currentFeed = feedRate;
146 | }
147 |
148 |
149 |
150 |
151 | /*
152 | * Assembler API that Compiler uses
153 | */
154 |
155 |
156 | public virtual void AppendMoveTo(Vector3d pos, double f, string comment = null)
157 | {
158 | if (in_retract) {
159 | last_retract_z = pos.z;
160 | pos.z = currentPos.z;
161 | }
162 |
163 | emit_travel(pos, f, comment);
164 | }
165 |
166 |
167 |
168 | public virtual void AppendCutTo(Vector3d pos, double feedRate, string comment = null)
169 | {
170 | if (InRetract)
171 | throw new Exception("BaseMillingAssembler.AppendMoveTo: in retract!");
172 |
173 | emit_cut(pos, feedRate, comment);
174 | }
175 |
176 |
177 |
178 |
179 | double last_retract_z = 0;
180 |
181 |
182 | public virtual void BeginRetract(double retractHeight, double feedRate, string comment = null)
183 | {
184 | if (in_retract)
185 | throw new Exception("BaseMillingAssembler.BeginRetract: already in retract!");
186 |
187 | last_retract_z = currentPos.z;
188 | Vector3d pos = currentPos;
189 | pos.z = retractHeight;
190 |
191 | emit_travel(pos, feedRate, comment);
192 |
193 | in_retract = true;
194 | }
195 |
196 |
197 | public virtual void EndRetract(double feedRate, string comment = null)
198 | {
199 | if (!in_retract)
200 | throw new Exception("BaseMillingAssembler.EndRetract: already in retract!");
201 |
202 | Vector3d pos = currentPos;
203 | pos.z = last_retract_z;
204 | emit_travel(pos, feedRate, comment);
205 |
206 | in_retract = false;
207 | }
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 | public virtual void BeginTravel() {
217 | if (in_travel)
218 | throw new Exception("BaseMillingAssembler.BeginTravel: already in travel!");
219 | in_travel = true;
220 | }
221 |
222 |
223 | public virtual void EndTravel()
224 | {
225 | if (in_travel == false)
226 | throw new Exception("BaseMillingAssembler.EndTravel: not in travel!");
227 | in_travel = false;
228 | }
229 |
230 |
231 | public virtual void AppendTravelTo(double x, double y, double z, double f)
232 | {
233 | throw new NotImplementedException("BaseMillingAssembler.AppendTravelTo");
234 | }
235 |
236 |
237 | public virtual void AppendComment(string comment)
238 | {
239 | Builder.AddCommentLine(comment);
240 | }
241 |
242 |
243 | public virtual void AppendDwell(int milliseconds, string comment = null)
244 | {
245 | Builder.BeginGLine(4, (comment != null) ? comment : "dwell" )
246 | .AppendI("P", milliseconds);
247 | }
248 |
249 |
250 |
251 |
252 | protected virtual void AddStandardHeader(SingleMaterialFFFSettings Settings)
253 | {
254 | Builder.AddCommentLine(" Generated on " + DateTime.Now.ToLongDateString() + " by Gradientspace gsSlicer");
255 | Builder.AddCommentLine(string.Format(" Printer: {0} {1}", Settings.Machine.ManufacturerName, Settings.Machine.ModelIdentifier));
256 | Builder.AddCommentLine(" Print Settings");
257 | Builder.AddCommentLine(" Layer Height: " + Settings.LayerHeightMM);
258 | Builder.AddCommentLine(" Nozzle Diameter: " + Settings.Machine.NozzleDiamMM + " Filament Diameter: " + Settings.Machine.FilamentDiamMM);
259 | Builder.AddCommentLine(" Extruder Temp: " + Settings.ExtruderTempC);
260 | Builder.AddCommentLine(string.Format(" Speeds Extrude: {0} Travel: {1} Z: {2}", Settings.RapidExtrudeSpeed, Settings.RapidTravelSpeed, Settings.ZTravelSpeed));
261 | Builder.AddCommentLine(string.Format(" Retract Distance: {0} Speed: {1}", Settings.RetractDistanceMM, Settings.RetractSpeed));
262 | Builder.AddCommentLine(string.Format(" Shells: {0} InteriorShells: {1}", Settings.Shells, Settings.InteriorSolidRegionShells));
263 | Builder.AddCommentLine(string.Format(" InfillX: {0}", Settings.SparseLinearInfillStepX));
264 | Builder.AddCommentLine(string.Format(" LayerRange: {0}-{1}", Settings.LayerRangeFilter.a, Settings.LayerRangeFilter.b));
265 | }
266 |
267 |
268 |
269 |
270 | }
271 |
272 |
273 | }
--------------------------------------------------------------------------------
/parsers/GenericGCodeParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.IO;
6 |
7 | namespace gs
8 | {
9 | public class GenericGCodeParser
10 | {
11 |
12 | public GCodeFile Parse(TextReader input)
13 | {
14 | GCodeFile file = new GCodeFile();
15 |
16 | int lines = 0;
17 | while ( input.Peek() >= 0 ) {
18 | string line = input.ReadLine();
19 | int nLineNum = lines++;
20 |
21 | GCodeLine l = ParseLine(line, nLineNum);
22 | file.AppendLine(l);
23 | }
24 |
25 | return file;
26 | }
27 |
28 |
29 |
30 | virtual protected GCodeLine ParseLine(string line, int nLineNum)
31 | {
32 | if (line.Length == 0)
33 | return make_blank(nLineNum);
34 | if (line[0] == ';')
35 | return make_comment(line, nLineNum);
36 |
37 | // strip off trailing comment
38 | string comment = null;
39 | int ci = line.IndexOf(';');
40 | if ( ci < 0 ) {
41 | int bo = line.IndexOf('(');
42 | int bc = line.IndexOf(')');
43 | if ( bo >= 0 && bc > 0 )
44 | ci = bo;
45 | }
46 | if ( ci >= 1 ) {
47 | comment = line.Substring(ci);
48 | line = line.Substring(0, ci);
49 | }
50 |
51 |
52 | string[] tokens = line.Split( (char[])null , StringSplitOptions.RemoveEmptyEntries);
53 |
54 | // handle extra spaces at start...?
55 | if (tokens.Length == 0)
56 | return make_blank(nLineNum);
57 |
58 | GCodeLine gcode = null;
59 | switch ( tokens[0][0]) {
60 | case ';':
61 | gcode = make_comment(line, nLineNum);
62 | break;
63 | case 'N':
64 | gcode = make_N_code_line(line, tokens, nLineNum);
65 | break;
66 | case 'G':
67 | case 'M':
68 | gcode = make_GM_code_line(line, tokens, nLineNum);
69 | break;
70 | case ':':
71 | gcode = make_control_line(line, tokens, nLineNum);
72 | break;
73 | default:
74 | gcode = make_string_line(line, nLineNum);
75 | break;
76 | }
77 |
78 | if ( comment != null )
79 | gcode.comment = comment;
80 |
81 | return gcode;
82 | }
83 |
84 |
85 |
86 |
87 | // G### and M### code lines
88 | virtual protected GCodeLine make_GM_code_line(string line, string[] tokens, int nLineNum)
89 | {
90 | GCodeLine.LType eType = GCodeLine.LType.UnknownCode;
91 | if (tokens[0][0] == 'G')
92 | eType = GCodeLine.LType.GCode;
93 | else if (tokens[0][0] == 'M')
94 | eType = GCodeLine.LType.MCode;
95 |
96 | GCodeLine l = new GCodeLine(nLineNum, eType);
97 | l.orig_string = line;
98 |
99 | l.N = int.Parse(tokens[0].Substring(1));
100 |
101 | // [TODO] comments
102 |
103 | if (eType == GCodeLine.LType.UnknownCode) {
104 | if (tokens.Length > 1)
105 | l.parameters = parse_parameters(tokens, 1);
106 | } else {
107 | l.code = int.Parse(tokens[0].Substring(1));
108 | if (tokens.Length > 1)
109 | l.parameters = parse_parameters(tokens, 1);
110 | }
111 |
112 | return l;
113 | }
114 |
115 |
116 |
117 | // N### lines
118 | virtual protected GCodeLine make_N_code_line(string line, string[] tokens, int nLineNum)
119 | {
120 | GCodeLine.LType eType = GCodeLine.LType.UnknownCode;
121 | if (tokens[1][0] == 'G')
122 | eType = GCodeLine.LType.GCode;
123 | else if (tokens[1][0] == 'M')
124 | eType = GCodeLine.LType.MCode;
125 |
126 | GCodeLine l = new GCodeLine(nLineNum, eType);
127 | l.orig_string = line;
128 |
129 | l.N = int.Parse(tokens[0].Substring(1));
130 |
131 | // [TODO] comments
132 |
133 | if (eType == GCodeLine.LType.UnknownCode) {
134 | if (tokens.Length > 1)
135 | l.parameters = parse_parameters(tokens, 1);
136 | } else {
137 | l.code = int.Parse(tokens[1].Substring(1));
138 | if (tokens.Length > 2)
139 | l.parameters = parse_parameters(tokens, 2);
140 | }
141 |
142 | return l;
143 | }
144 |
145 |
146 |
147 |
148 |
149 |
150 | // any line we can't understand
151 | virtual protected GCodeLine make_string_line(string line, int nLineNum)
152 | {
153 | GCodeLine l = new GCodeLine(nLineNum, GCodeLine.LType.UnknownString);
154 | l.orig_string = line;
155 | return l;
156 | }
157 |
158 |
159 |
160 | // :IF, :ENDIF, :ELSE
161 | virtual protected GCodeLine make_control_line(string line, string[] tokens, int nLineNum)
162 | {
163 | // figure out command type
164 | string command = tokens[0].Substring(1);
165 | GCodeLine.LType eType = GCodeLine.LType.UnknownControl;
166 | if (command.Equals("if", StringComparison.OrdinalIgnoreCase))
167 | eType = GCodeLine.LType.If;
168 | else if (command.Equals("else", StringComparison.OrdinalIgnoreCase))
169 | eType = GCodeLine.LType.Else;
170 | else if (command.Equals("endif", StringComparison.OrdinalIgnoreCase))
171 | eType = GCodeLine.LType.EndIf;
172 |
173 | GCodeLine l = new GCodeLine(nLineNum, eType);
174 | l.orig_string = line;
175 |
176 | if (tokens.Length > 1)
177 | l.parameters = parse_parameters(tokens, 1);
178 |
179 | return l;
180 | }
181 |
182 |
183 |
184 | // line starting with ;
185 | virtual protected GCodeLine make_comment(string line, int nLineNum)
186 | {
187 | GCodeLine l = new GCodeLine(nLineNum, GCodeLine.LType.Comment);
188 |
189 | l.orig_string = line;
190 | int iStart = line.IndexOf(';');
191 | l.comment = line.Substring(iStart);
192 | return l;
193 | }
194 |
195 |
196 | // line with no text at all
197 | virtual protected GCodeLine make_blank(int nLineNum)
198 | {
199 | return new GCodeLine(nLineNum, GCodeLine.LType.Blank);
200 | }
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | virtual protected GCodeParam[] parse_parameters(string[] tokens, int iStart, int iEnd = -1)
209 | {
210 | if (iEnd == -1)
211 | iEnd = tokens.Length;
212 |
213 | int N = iEnd - iStart;
214 | GCodeParam[] paramList = new GCodeParam[N];
215 |
216 | for ( int ti = iStart; ti < iEnd; ++ti ) {
217 | int pi = ti - iStart;
218 |
219 | bool bHandled = false;
220 | if ( tokens[ti].Contains('=') ) {
221 | parse_equals_parameter(tokens[ti], ref paramList[pi]);
222 | bHandled = true;
223 |
224 | } else if ( tokens[ti][0] == 'G' || tokens[ti][0] == 'M' ) {
225 | parse_code_parameter(tokens[ti], ref paramList[pi]);
226 | bHandled = true;
227 |
228 | } else if ( is_num_parameter(tokens[ti]) > 0 ) {
229 | parse_noequals_num_parameter( tokens[ti], ref paramList[pi] );
230 | bHandled = true;
231 |
232 | } else if ( tokens[ti].Length == 1 ) {
233 | paramList[pi].type = GCodeParam.PType.NoValue;
234 | paramList[pi].identifier = tokens[ti];
235 | bHandled = true;
236 | }
237 |
238 | if (!bHandled) {
239 | paramList[pi].type = GCodeParam.PType.TextValue;
240 | paramList[pi].textValue = tokens[ti];
241 | }
242 | }
243 |
244 | return paramList;
245 | }
246 |
247 |
248 |
249 |
250 | virtual protected bool parse_code_parameter(string token, ref GCodeParam param)
251 | {
252 | param.type = GCodeParam.PType.Code;
253 | param.identifier = token.Substring(0,1);
254 |
255 | string value = token.Substring(1);
256 | GCodeUtil.NumberType numType = GCodeUtil.GetNumberType(value);
257 | if (numType == GCodeUtil.NumberType.Integer)
258 | param.intValue = int.Parse(value);
259 |
260 | return true;
261 | }
262 |
263 |
264 | virtual protected int is_num_parameter(string token)
265 | {
266 | int N = token.Length;
267 |
268 | bool contains_number = false;
269 | for (int i = 0; i < N && contains_number == false; ++i) {
270 | if (Char.IsDigit(token[i]))
271 | contains_number = true;
272 | }
273 | if (!contains_number)
274 | return -1;
275 |
276 | for ( int i = 1; i < N; ++i ) {
277 | string sub = token.Substring(i);
278 | GCodeUtil.NumberType numtype = GCodeUtil.GetNumberType(sub);
279 | if (numtype != GCodeUtil.NumberType.NotANumber) {
280 | return i;
281 | }
282 | }
283 | return -1;
284 | }
285 |
286 |
287 | virtual protected bool parse_noequals_num_parameter(string token, ref GCodeParam param)
288 | {
289 | int i = is_num_parameter(token);
290 | if ( i >= 0 )
291 | return parse_value_param(token, i, 0, ref param);
292 | return false;
293 | }
294 |
295 |
296 |
297 | virtual protected bool parse_equals_parameter(string token, ref GCodeParam param)
298 | {
299 | int i = token.IndexOf('=');
300 | return parse_value_param(token, i, 1, ref param);
301 | }
302 |
303 |
304 |
305 | virtual protected bool parse_value_param(string token, int split, int skip, ref GCodeParam param)
306 | {
307 | param.identifier = token.Substring(0, split);
308 |
309 | string value = token.Substring(split + skip, token.Length - (split+skip));
310 |
311 | try {
312 | GCodeUtil.NumberType numType = GCodeUtil.GetNumberType(value);
313 | if (numType == GCodeUtil.NumberType.Decimal) {
314 | param.type = GCodeParam.PType.DoubleValue;
315 | param.doubleValue = double.Parse(value);
316 | return true;
317 | } else if (numType == GCodeUtil.NumberType.Integer) {
318 | param.type = GCodeParam.PType.IntegerValue;
319 | param.intValue = int.Parse(value);
320 | return true;
321 | }
322 | } catch {
323 | // just continue on and do generic string param
324 | }
325 |
326 | param.type = GCodeParam.PType.TextValue;
327 | param.textValue = value;
328 | return true;
329 | }
330 |
331 |
332 | }
333 | }
334 |
--------------------------------------------------------------------------------
/settings/AdditiveSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using g3;
3 |
4 | namespace gs
5 | {
6 | public enum MachineClass
7 | {
8 | Unknown,
9 | PlasticFFFPrinter,
10 | MetalSLSPrinter
11 | }
12 |
13 |
14 | public abstract class MachineInfo
15 | {
16 | protected static string UnknownUUID = "00000000-0000-0000-0000-000000000000";
17 |
18 | public string ManufacturerName = "Unknown";
19 | public string ManufacturerUUID = UnknownUUID;
20 | public string ModelIdentifier = "Machine";
21 | public string ModelUUID = UnknownUUID;
22 | public MachineClass Class = MachineClass.Unknown;
23 |
24 | public double BedSizeXMM = 100;
25 | public double BedSizeYMM = 100;
26 | public double MaxHeightMM = 100;
27 |
28 | // These factors define the output coordinate system
29 |
30 | // BedOriginFactorX:
31 | // 0 : the origin is at the left of the build plate
32 | // 0.5 : the origin is at the middle of the build plate
33 | // 1 : the origin is at the right of the build plate
34 |
35 | // BedOriginFactorY:
36 | // 0 : the origin is at the front of the build plate
37 | // 0.5 : the origin is at the middle of the build plate
38 | // 1 : the origin is at the back of the build plate
39 |
40 | public double BedOriginFactorX = 0;
41 | public double BedOriginFactorY = 0;
42 |
43 | public abstract T CloneAs() where T : class;
44 | protected virtual void CopyFieldsTo(MachineInfo to)
45 | {
46 | to.ManufacturerName = this.ManufacturerName;
47 | to.ManufacturerUUID = this.ManufacturerUUID;
48 | to.ModelIdentifier = this.ModelIdentifier;
49 | to.ModelUUID = this.ModelUUID;
50 | to.Class = this.Class;
51 | to.BedSizeXMM = this.BedSizeXMM;
52 | to.BedSizeYMM = this.BedSizeYMM;
53 | to.MaxHeightMM = this.MaxHeightMM;
54 | }
55 | }
56 |
57 |
58 |
59 | public class FFFMachineInfo : MachineInfo
60 | {
61 | /*
62 | * printer mechanics
63 | */
64 | public double NozzleDiamMM = 0.4;
65 | public double FilamentDiamMM = 1.75;
66 |
67 | public double MinLayerHeightMM = 0.2;
68 | public double MaxLayerHeightMM = 0.2;
69 |
70 | /*
71 | * Temperatures
72 | */
73 |
74 | public int MinExtruderTempC = 20;
75 | public int MaxExtruderTempC = 230;
76 |
77 | public bool HasHeatedBed = false;
78 | public int MinBedTempC = 0;
79 | public int MaxBedTempC = 0;
80 |
81 | /*
82 | * All units are mm/min = (mm/s * 60)
83 | */
84 | public int MaxExtrudeSpeedMMM = 50 * 60;
85 | public int MaxTravelSpeedMMM = 100 * 60;
86 | public int MaxZTravelSpeedMMM = 20 * 60;
87 | public int MaxRetractSpeedMMM = 20 * 60;
88 |
89 |
90 | /*
91 | * bed levelling
92 | */
93 | public bool HasAutoBedLeveling = false;
94 | public bool EnableAutoBedLeveling = false;
95 |
96 |
97 | /*
98 | * Hacks?
99 | */
100 |
101 | public double MinPointSpacingMM = 0.1; // Avoid emitting gcode extrusion points closer than this spacing.
102 | // This is a workaround for the fact that many printers do not gracefully
103 | // handle very tiny sequential extrusion steps. This setting could be
104 | // configured using CalibrationModelGenerator.MakePrintStepSizeTest() with
105 | // all other cleanup steps disabled.
106 | // [TODO] this is actually speed-dependent...
107 |
108 | public override T CloneAs()
109 | {
110 | FFFMachineInfo fi = new FFFMachineInfo();
111 | this.CopyFieldsTo(fi);
112 | return fi as T;
113 | }
114 | protected virtual void CopyFieldsTo(FFFMachineInfo to)
115 | {
116 | base.CopyFieldsTo(to);
117 |
118 | to.NozzleDiamMM = this.NozzleDiamMM;
119 | to.FilamentDiamMM = this.FilamentDiamMM;
120 | to.MinLayerHeightMM = this.MinLayerHeightMM;
121 | to.MaxHeightMM = this.MaxHeightMM;
122 | to.MinExtruderTempC = this.MaxExtruderTempC;
123 | to.HasHeatedBed = this.HasHeatedBed;
124 | to.MinBedTempC = this.MinBedTempC;
125 | to.MaxBedTempC = this.MaxBedTempC;
126 | to.MaxExtrudeSpeedMMM = this.MaxExtrudeSpeedMMM;
127 | to.MaxTravelSpeedMMM = this.MaxTravelSpeedMMM;
128 | to.MaxZTravelSpeedMMM = this.MaxZTravelSpeedMMM;
129 | to.MaxRetractSpeedMMM = this.MaxRetractSpeedMMM;
130 | to.MinPointSpacingMM = this.MinPointSpacingMM;
131 |
132 | to.EnableAutoBedLeveling = this.EnableAutoBedLeveling;
133 | to.HasAutoBedLeveling = this.HasAutoBedLeveling;
134 |
135 | to.ManufacturerName = this.ManufacturerName;
136 | to.ManufacturerUUID = this.ManufacturerUUID;
137 | to.ModelIdentifier = this.ModelIdentifier;
138 | to.ModelUUID = this.ModelUUID;
139 | to.Class = this.Class;
140 | to.BedSizeXMM = this.BedSizeXMM;
141 | to.BedSizeYMM = this.BedSizeYMM;
142 | to.MaxHeightMM = this.MaxHeightMM;
143 | to.BedOriginFactorX = this.BedOriginFactorX;
144 | to.BedOriginFactorY = this.BedOriginFactorY;
145 | }
146 | }
147 |
148 |
149 |
150 | public abstract class PlanarAdditiveSettings
151 | {
152 | ///
153 | /// This is the "name" of this settings (eg user identifier)
154 | ///
155 | public string Identifier = "Defaults";
156 |
157 | public double LayerHeightMM = 0.2;
158 |
159 |
160 | public string ClassTypeName {
161 | get { return GetType().ToString(); }
162 | }
163 |
164 |
165 | public abstract MachineInfo BaseMachine { get; set; }
166 |
167 | public abstract T CloneAs() where T : class;
168 | protected virtual void CopyFieldsTo(PlanarAdditiveSettings to)
169 | {
170 | to.Identifier = this.Identifier;
171 | to.LayerHeightMM = this.LayerHeightMM;
172 | }
173 | }
174 |
175 |
176 |
177 | public class SingleMaterialFFFSettings : PlanarAdditiveSettings
178 | {
179 | // This is a bit of an odd place for this, but settings are where we actually
180 | // know what assembler we should be using...
181 | public virtual AssemblerFactoryF AssemblerType() {
182 | throw new NotImplementedException("Settings.AssemblerType() not provided");
183 | }
184 |
185 |
186 | protected FFFMachineInfo machineInfo;
187 | public FFFMachineInfo Machine {
188 | get { if (machineInfo == null) machineInfo = new FFFMachineInfo(); return machineInfo; }
189 | set { machineInfo = value; }
190 | }
191 |
192 |
193 | public override MachineInfo BaseMachine {
194 | get { return Machine; }
195 | set { if (value is FFFMachineInfo)
196 | machineInfo = value as FFFMachineInfo;
197 | else
198 | throw new Exception("SingleMaterialFFFSettings.Machine.set: type is not FFFMachineInfo!");
199 | }
200 | }
201 |
202 | /*
203 | * Temperatures
204 | */
205 |
206 | public int ExtruderTempC = 210;
207 | public int HeatedBedTempC = 0;
208 |
209 | /*
210 | * Distances.
211 | * All units are mm
212 | */
213 |
214 | public bool EnableRetraction = true;
215 | public double RetractDistanceMM = 1.3;
216 | public double MinRetractTravelLength = 2.5; // don't retract if we are travelling less than this distance
217 |
218 |
219 | /*
220 | * Speeds.
221 | * All units are mm/min = (mm/s * 60)
222 | */
223 |
224 | // these are all in units of millimeters/minute
225 | public double RetractSpeed = 25 * 60; // 1500
226 |
227 | public double ZTravelSpeed = 23 * 60; // 1380
228 |
229 | public double RapidTravelSpeed = 150 * 60; // 9000
230 |
231 | public double CarefulExtrudeSpeed = 30 * 60; // 1800
232 | public double RapidExtrudeSpeed = 90 * 60; // 5400
233 | public double MinExtrudeSpeed = 20 * 60; // 600
234 |
235 | public double OuterPerimeterSpeedX = 0.5;
236 |
237 | public double FanSpeedX = 1.0; // default fan speed, fraction of max speed (generally unknown)
238 |
239 |
240 | // Settings for z-lift on rapid travel moves
241 | public bool TravelLiftEnabled { get; set; } = true;
242 | public double TravelLiftHeight { get; set; } = 0.2;
243 | public double TravelLiftDistanceThreshold { get; set; } = 5d;
244 |
245 | /*
246 | * Shells
247 | */
248 | public int Shells = 2;
249 | public int InteriorSolidRegionShells = 0; // how many shells to add around interior solid regions (eg roof/floor)
250 | public bool OuterShellLast = false; // do outer shell last (better quality but worse precision)
251 |
252 | /*
253 | * Roof/Floors
254 | */
255 | public int RoofLayers = 2;
256 | public int FloorLayers = 2;
257 |
258 | /*
259 | * Solid fill settings
260 | */
261 | public double ShellsFillNozzleDiamStepX = 1.0; // multipler on Machine.NozzleDiamMM, defines spacing between adjacent
262 | // nested shells/perimeters. If < 1, they overlap.
263 | public double SolidFillNozzleDiamStepX = 1.0; // multipler on Machine.NozzleDiamMM, defines spacing between adjacent
264 | // solid fill parallel lines. If < 1, they overlap.
265 | public double SolidFillBorderOverlapX = 0.25f; // this is a multiplier on Machine.NozzleDiamMM, defines how far we
266 | // overlap solid fill onto border shells (if 0, no overlap)
267 |
268 | /*
269 | * Sparse infill settings
270 | */
271 | public double SparseLinearInfillStepX = 5.0; // this is a multiplier on FillPathSpacingMM
272 |
273 | public double SparseFillBorderOverlapX = 0.25f; // this is a multiplier on Machine.NozzleDiamMM, defines how far we
274 | // overlap solid fill onto border shells (if 0, no overlap)
275 |
276 | /*
277 | * Start layer controls
278 | */
279 | public int StartLayers = 0; // number of start layers, special handling
280 | public double StartLayerHeightMM = 0; // height of start layers. If 0, same as regular layers
281 |
282 |
283 | /*
284 | * Support settings
285 | */
286 | public bool GenerateSupport = true; // should we auto-generate support
287 | public double SupportOverhangAngleDeg = 35; // standard "support angle"
288 | public double SupportSpacingStepX = 5.0; // usage depends on support technique?
289 | public double SupportVolumeScale = 1.0; // multiplier on extrusion volume
290 | public bool EnableSupportShell = true; // should we print a shell around support areas
291 | public double SupportAreaOffsetX = -0.5; // 2D inset/outset added to support regions. Multiplier on Machine.NozzleDiamMM.
292 | public double SupportSolidSpace = 0.35f; // how much space to leave between model and support
293 | public double SupportRegionJoinTolX = 2.0; // support regions within this distance will be merged via topological dilation. Multiplier on NozzleDiamMM.
294 | public bool EnableSupportReleaseOpt = true; // should we use support release optimization
295 | public double SupportReleaseGap = 0.2f; // how much space do we leave
296 | public double SupportMinDimension = 1.5; // minimal size of support polygons
297 | public bool SupportMinZTips = true; // turn on/off detection of support 'tip' regions, ie tiny islands.
298 | public double SupportPointDiam = 2.5f; // width of per-layer support "points" (keep larger than SupportMinDimension!)
299 | public int SupportPointSides = 4; // number of vertices for support-point polygons (circles)
300 |
301 |
302 | /*
303 | * Bridging settings
304 | */
305 | public bool EnableBridging = true;
306 | public double MaxBridgeWidthMM = 10.0;
307 | public double BridgeFillNozzleDiamStepX = 0.85; // multiplier on FillPathSpacingMM
308 | public double BridgeVolumeScale = 1.0; // multiplier on extrusion volume
309 | public double BridgeExtrudeSpeedX = 0.5; // multiplier on CarefulExtrudeSpeed
310 |
311 |
312 | /*
313 | * Toolpath filtering options
314 | */
315 | public double MinLayerTime = 5.0; // minimum layer time in seconds
316 | public bool ClipSelfOverlaps = false; // if true, try to remove portions of toolpaths that will self-overlap
317 | public double SelfOverlapToleranceX = 0.75; // what counts as 'self-overlap'. this is a multiplier on NozzleDiamMM
318 |
319 | /*
320 | * Debug/Utility options
321 | */
322 |
323 | public Interval1i LayerRangeFilter = new Interval1i(0, 999999999); // only compute slices in this range
324 |
325 |
326 |
327 |
328 | /*
329 | * functions that calculate derived values
330 | * NOTE: these cannot be properties because then they will be json-serialized!
331 | */
332 | public double ShellsFillPathSpacingMM() {
333 | return Machine.NozzleDiamMM * ShellsFillNozzleDiamStepX;
334 | }
335 | public double SolidFillPathSpacingMM() {
336 | return Machine.NozzleDiamMM * SolidFillNozzleDiamStepX;
337 | }
338 | public double BridgeFillPathSpacingMM() {
339 | return Machine.NozzleDiamMM * BridgeFillNozzleDiamStepX;
340 | }
341 |
342 |
343 | public override T CloneAs()
344 | {
345 | SingleMaterialFFFSettings copy = new SingleMaterialFFFSettings();
346 | this.CopyFieldsTo(copy);
347 | return copy as T;
348 | }
349 | protected virtual void CopyFieldsTo(SingleMaterialFFFSettings to)
350 | {
351 | base.CopyFieldsTo(to);
352 | to.machineInfo = this.machineInfo.CloneAs();
353 |
354 | to.ExtruderTempC = this.ExtruderTempC;
355 | to.HeatedBedTempC = this.HeatedBedTempC;
356 | to.EnableRetraction = this.EnableRetraction;
357 | to.RetractDistanceMM = this.RetractDistanceMM;
358 | to.MinRetractTravelLength = this.MinRetractTravelLength;
359 |
360 | to.RetractSpeed = this.RetractSpeed;
361 | to.ZTravelSpeed = this.ZTravelSpeed;
362 | to.RapidTravelSpeed = this.RapidTravelSpeed;
363 | to.CarefulExtrudeSpeed = this.CarefulExtrudeSpeed;
364 | to.RapidExtrudeSpeed = this.RapidExtrudeSpeed;
365 | to.MinExtrudeSpeed = this.MinExtrudeSpeed;
366 | to.OuterPerimeterSpeedX = this.OuterPerimeterSpeedX;
367 | to.FanSpeedX = this.FanSpeedX;
368 |
369 | to.TravelLiftEnabled = this.TravelLiftEnabled;
370 | to.TravelLiftHeight = this.TravelLiftHeight;
371 | to.TravelLiftDistanceThreshold = this.TravelLiftDistanceThreshold;
372 |
373 | to.Shells = this.Shells;
374 | to.InteriorSolidRegionShells = this.InteriorSolidRegionShells;
375 | to.OuterShellLast = this.OuterShellLast;
376 | to.RoofLayers = this.RoofLayers;
377 | to.FloorLayers = this.FloorLayers;
378 |
379 | to.ShellsFillNozzleDiamStepX = this.ShellsFillNozzleDiamStepX;
380 | to.SolidFillNozzleDiamStepX = this.SolidFillNozzleDiamStepX;
381 | to.SolidFillBorderOverlapX = this.SolidFillBorderOverlapX;
382 |
383 | to.SparseLinearInfillStepX = this.SparseLinearInfillStepX;
384 | to.SparseFillBorderOverlapX = this.SparseFillBorderOverlapX;
385 |
386 | to.StartLayers = this.StartLayers;
387 | to.StartLayerHeightMM = this.StartLayerHeightMM;
388 |
389 | to.GenerateSupport = this.GenerateSupport;
390 | to.SupportOverhangAngleDeg = this.SupportOverhangAngleDeg;
391 | to.SupportSpacingStepX = this.SupportSpacingStepX;
392 | to.SupportVolumeScale = this.SupportVolumeScale;
393 | to.EnableSupportShell = this.EnableSupportShell;
394 | to.SupportAreaOffsetX = this.SupportAreaOffsetX;
395 | to.SupportSolidSpace = this.SupportSolidSpace;
396 | to.SupportRegionJoinTolX = this.SupportRegionJoinTolX;
397 | to.EnableSupportReleaseOpt = this.EnableSupportReleaseOpt;
398 | to.SupportReleaseGap = this.SupportReleaseGap;
399 | to.SupportMinDimension = this.SupportMinDimension;
400 | to.SupportMinZTips = this.SupportMinZTips;
401 | to.SupportPointDiam = this.SupportPointDiam;
402 | to.SupportPointSides = this.SupportPointSides;
403 |
404 | to.EnableBridging = this.EnableBridging;
405 | to.MaxBridgeWidthMM = this.MaxBridgeWidthMM;
406 | to.BridgeFillNozzleDiamStepX = this.BridgeFillNozzleDiamStepX;
407 | to.BridgeVolumeScale = this.BridgeVolumeScale;
408 | to.BridgeExtrudeSpeedX = this.BridgeExtrudeSpeedX;
409 |
410 |
411 | to.MinLayerTime = this.MinLayerTime;
412 | to.ClipSelfOverlaps = this.ClipSelfOverlaps;
413 | to.SelfOverlapToleranceX = this.SelfOverlapToleranceX;
414 |
415 | to.LayerRangeFilter = this.LayerRangeFilter;
416 | }
417 |
418 | }
419 |
420 |
421 |
422 |
423 | // just for naming...
424 | public class GenericRepRapSettings : SingleMaterialFFFSettings
425 | {
426 | public override AssemblerFactoryF AssemblerType() {
427 | return RepRapAssembler.Factory;
428 | }
429 |
430 |
431 | public override T CloneAs()
432 | {
433 | GenericRepRapSettings copy = new GenericRepRapSettings();
434 | this.CopyFieldsTo(copy);
435 | return copy as T;
436 | }
437 |
438 |
439 | }
440 |
441 | }
--------------------------------------------------------------------------------
/assemblers/BaseDepositionAssembler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using g3;
6 | using gs;
7 |
8 | namespace gs
9 | {
10 |
11 | public interface IGCodeAssembler
12 | {
13 | }
14 |
15 | public interface IDepositionAssembler : IGCodeAssembler
16 | {
17 | }
18 |
19 |
20 | public delegate BaseDepositionAssembler AssemblerFactoryF(GCodeBuilder builder, SingleMaterialFFFSettings settings);
21 |
22 |
23 | ///
24 | /// Assembler translates high-level commands from Compiler (eg MoveTo, ExtrudeTo, BeginRetract, etc)
25 | /// into GCode instructions, which it passes to GCodeBuilder instance.
26 | ///
27 | /// To do this, Assembler maintains state machine for things like current nozzle position,
28 | /// extruder position, etc.
29 | ///
30 | /// TODO:
31 | /// - need to reset accumulated extrusion distance to 0 once in a while,
32 | /// to avoid precision issues.
33 | /// - support relative mode for position and extruder
34 | ///
35 | ///
36 | ///
37 | public abstract class BaseDepositionAssembler : IDepositionAssembler
38 | {
39 | public GCodeBuilder Builder;
40 |
41 | public enum ExtrudeParamType {
42 | ExtrudeParamA, ExtrudeParamE
43 | }
44 |
45 | ///
46 | /// Different machines use A or E for the extrude parameter
47 | ///
48 | public ExtrudeParamType ExtrudeParam = ExtrudeParamType.ExtrudeParamE;
49 |
50 | ///
51 | /// To keep things simple, we use the absolute coordinates of the slice polygons
52 | /// at the higher levels. However the printer often operates in some other coordinate
53 | /// system, for example relative to front-left corner. PositionShift is added to all x/y
54 | /// coordinates before they are passed to the GCodeBuilder.
55 | ///
56 | public Vector2d PositionShift = Vector2d.Zero;
57 |
58 |
59 | ///
60 | /// check that all points lie within bounds
61 | ///
62 | public bool EnableBoundsChecking = true;
63 |
64 | ///
65 | /// if EnableBoundsChecking=true, will assert if we try to move outside these bounds
66 | ///
67 | public AxisAlignedBox2d PositionBounds = AxisAlignedBox2d.Infinite;
68 |
69 |
70 | ///
71 | /// Generally, deposition-style 3D printers cannot handle large numbers of very small GCode steps.
72 | /// The result will be very chunky.
73 | /// So, we will cluster sequences of tiny steps into something that can actually be printed.
74 | ///
75 | public double MinExtrudeStepDistance = 0.0f; // is set to FFFMachineInfo.MinPointSpacingMM in constructor below!!
76 |
77 |
78 | // Makerbot uses G1 for travel as well as extrude, so need to be able to override this
79 | public int TravelGCode = 0;
80 |
81 | public bool OmitDuplicateZ = false;
82 | public bool OmitDuplicateF = false;
83 | public bool OmitDuplicateE = false;
84 |
85 | // threshold for omitting "duplicate" Z/F/E parameters
86 | public double MoveEpsilon = 0.00001;
87 |
88 |
89 | public BaseDepositionAssembler(GCodeBuilder useBuilder, FFFMachineInfo machineInfo)
90 | {
91 | Builder = useBuilder;
92 | currentPos = Vector3d.Zero;
93 | lastPos = Vector3d.Zero;
94 | extruderA = 0;
95 | currentFeed = 0;
96 |
97 | Vector2d originRepositioning = new Vector2d(machineInfo.BedOriginFactorX, machineInfo.BedOriginFactorY);
98 | Vector2d bedSize = new Vector2d(machineInfo.BedSizeXMM, machineInfo.BedSizeYMM);
99 | PositionShift = originRepositioning*bedSize;
100 |
101 | MinExtrudeStepDistance = machineInfo.MinPointSpacingMM;
102 | }
103 |
104 |
105 | /*
106 | * Subclasses must implement these
107 | */
108 |
109 | public abstract void AppendHeader();
110 | public abstract void AppendFooter();
111 | public abstract void EnableFan();
112 | public abstract void DisableFan();
113 | public abstract void UpdateProgress(int i);
114 | public abstract void ShowMessage(string s);
115 |
116 | /*
117 | * These seem standard enough that we will provide a default implementation
118 | */
119 | public virtual void SetExtruderTargetTemp(int temp, string comment = "set extruder temp C")
120 | {
121 | Builder.BeginMLine(104, comment).AppendI("S", temp);
122 | }
123 | public virtual void SetExtruderTargetTempAndWait(int temp, string comment = "set extruder temp C, and wait")
124 | {
125 | Builder.BeginMLine(109, comment).AppendI("S", temp);
126 | }
127 |
128 | public virtual void SetBedTargetTemp(int temp, string comment = "set bed temp C")
129 | {
130 | Builder.BeginMLine(140, comment).AppendI("S", temp);
131 | }
132 | public virtual void SetBedTargetTempAndWait(int temp, string comment = "set bed temp C, and wait")
133 | {
134 | Builder.BeginMLine(190, comment).AppendI("S", temp);
135 | }
136 |
137 |
138 | /*
139 | * Position commands
140 | */
141 |
142 | protected Vector3d currentPos;
143 | protected Vector3d lastPos;
144 | public Vector3d NozzlePosition
145 | {
146 | get {
147 | return lastPos;
148 | }
149 | }
150 |
151 | protected double currentFeed;
152 | public double FeedRate
153 | {
154 | get { return currentFeed; }
155 | }
156 |
157 | protected double extruderA;
158 | public double ExtruderA
159 | {
160 | get { return extruderA; }
161 | }
162 |
163 | protected bool in_retract;
164 | protected double retractA;
165 | public bool InRetract
166 | {
167 | get { return in_retract; }
168 | }
169 |
170 | protected bool in_travel;
171 | public bool InTravel
172 | {
173 | get { return in_travel; }
174 | }
175 |
176 | public bool InExtrude {
177 | get { return InTravel == false; }
178 | }
179 |
180 |
181 |
182 |
183 | /*
184 | * Code below is all to support MinExtrudeStepDistance > 0
185 | * In that case, we want to only emit the next gcode extrusion point once we have travelled
186 | * at least MinExtrudeStepDistance distance. To do that, we will skip points
187 | * until we have moved far enough, then emit one.
188 | *
189 | * Currently we are saving all the skipped points in a queue, although we only use
190 | * the last two to emit. Current strategy is to lerp along the last line segment,
191 | * so that the emitted point is exactly at linear-arc-length MinExtrudeStepDistance.
192 | * The remainder of the last line goes back on the queue.
193 | *
194 | * This does end up clipping sharp corners if they are made of multiple closely-spaced
195 | * points. However the scale of the clipping should be on the order of the filament
196 | * width, so it probably doesn't make a visual difference. And (anecdotally) it may
197 | * actually produce cleaner results in the corners...
198 | *
199 | * [TODO] This is actually speed-dependent. We could modulate the clipping step size
200 | * by the movement speed. Or, we could slow down to hit the higher precision?
201 | * Might be preferable to just be consistent per layer, though...
202 | */
203 |
204 |
205 |
206 | // stores info we need to emit an extrude gcode point
207 | protected struct QueuedExtrude
208 | {
209 | public Vector3d toPos;
210 | public double feedRate;
211 | public double extruderA;
212 | public char extrudeChar;
213 | public string comment;
214 |
215 | static public QueuedExtrude lerp(ref QueuedExtrude a, ref QueuedExtrude b, double t)
216 | {
217 | QueuedExtrude newp = new QueuedExtrude();
218 | newp.toPos = Vector3d.Lerp(a.toPos, b.toPos, t);
219 | newp.feedRate = Math.Max(a.feedRate, b.feedRate);
220 | newp.extruderA = MathUtil.Lerp(a.extruderA, b.extruderA, t);
221 | newp.extrudeChar = a.extrudeChar;
222 | newp.comment = (a.comment == null) ? a.comment : b.comment;
223 | return newp;
224 | }
225 | }
226 |
227 |
228 | protected QueuedExtrude[] extrude_queue = new QueuedExtrude[1024];
229 | protected double extrude_queue_len = 0;
230 | int next_queue_index = 0;
231 |
232 |
233 | // we do not actually queue travel moves, but we might need to flush extrude queue
234 | protected virtual void queue_travel(Vector3d toPos, double feedRate, string comment)
235 | {
236 | Util.gDevAssert(InExtrude == false);
237 | if (EnableBoundsChecking && PositionBounds.Contains(toPos.xy) == false)
238 | throw new Exception("BaseDepositionAssembler.queue_move: tried to move outside of bounds!");
239 |
240 | lastPos = toPos;
241 |
242 | // flush any pending extrude
243 | flush_extrude_queue();
244 |
245 | emit_travel(toPos, feedRate, comment);
246 | }
247 |
248 | // actually emit travel move gcode
249 | protected virtual void emit_travel(Vector3d toPos, double feedRate, string comment)
250 | {
251 | double write_x = toPos.x + PositionShift.x;
252 | double write_y = toPos.y + PositionShift.y;
253 |
254 | Builder.BeginGLine(TravelGCode, comment).
255 | AppendF("X", write_x).AppendF("Y", write_y);
256 |
257 | if (OmitDuplicateZ == false || MathUtil.EpsilonEqual(currentPos.z, toPos.z, MoveEpsilon) == false) {
258 | Builder.AppendF("Z", toPos.z);
259 | }
260 | if (OmitDuplicateF == false || MathUtil.EpsilonEqual(currentFeed, feedRate, MoveEpsilon) == false) {
261 | Builder.AppendF("F", feedRate);
262 | }
263 |
264 | currentPos = toPos;
265 | currentFeed = feedRate;
266 | }
267 |
268 |
269 | // push an extrude move onto queue
270 | protected virtual void queue_extrude(Vector3d toPos, double feedRate, double e, char extrudeChar, string comment, bool bIsRetract)
271 | {
272 | Util.gDevAssert(InExtrude || bIsRetract);
273 | if (EnableBoundsChecking && PositionBounds.Contains(toPos.xy) == false)
274 | throw new Exception("BaseDepositionAssembler.queue_extrude: tried to move outside of bounds!");
275 |
276 | lastPos = toPos;
277 |
278 | QueuedExtrude p = new QueuedExtrude() {
279 | toPos = toPos, feedRate = feedRate, extruderA = e, extrudeChar = extrudeChar, comment = comment
280 | };
281 |
282 | // we cannot queue a retract, so flush queue and emit the retract/unretract
283 | bool bForceEmit = (bIsRetract) || (toPos.z != NozzlePosition.z);
284 | if (bForceEmit) {
285 | flush_extrude_queue();
286 | emit_extrude(p);
287 | return;
288 | }
289 |
290 | // push this point onto queue. this will also update the extrude_queue_len
291 | double prev_len = extrude_queue_len;
292 | append_to_queue(p);
293 |
294 | // if we haven't moved far enough to emit a point, we wait
295 | if (extrude_queue_len < MinExtrudeStepDistance) {
296 | return;
297 | }
298 | // ok we moved far enough from last point to emit
299 |
300 | // if queue has one point, just emit it
301 | int last_i = next_queue_index-1;
302 | if (last_i == 0) {
303 | flush_extrude_queue();
304 | return;
305 | }
306 |
307 | // otherwise we lerp between last two points so that we emit at
308 | // point where accumulated linear arclength is exactly MinExtrudeStepDistance.
309 | double a = prev_len, b = extrude_queue_len;
310 | double t = (MinExtrudeStepDistance-a) / (b-a);
311 | Util.gDevAssert(t > -0.0001 && t < 1.0001);
312 | t = MathUtil.Clamp(t, 0, 1);
313 | QueuedExtrude last_p = extrude_queue[next_queue_index - 1];
314 | QueuedExtrude emit_p = QueuedExtrude.lerp(ref extrude_queue[next_queue_index-2], ref last_p, t);
315 |
316 | // emit and clear queue
317 | emit_extrude(emit_p);
318 | next_queue_index = 0;
319 | extrude_queue_len = 0;
320 |
321 | // now we re-submit last point. This pushes the remaining bit of the last segment
322 | // back onto the queue. (should we skip this if t > nearly-one?)
323 | queue_extrude(last_p.toPos, last_p.feedRate, last_p.extruderA, last_p.extrudeChar, last_p.comment, false);
324 | }
325 | protected virtual void queue_extrude_to(Vector3d toPos, double feedRate, double extrudeDist, string comment, bool bIsRetract)
326 | {
327 | if (ExtrudeParam == ExtrudeParamType.ExtrudeParamA)
328 | queue_extrude(toPos, feedRate, extrudeDist, 'A', comment, bIsRetract);
329 | else
330 | queue_extrude(toPos, feedRate, extrudeDist, 'E', comment, bIsRetract);
331 | }
332 |
333 | // emit gcode for an extrude move
334 | protected virtual void emit_extrude(QueuedExtrude p)
335 | {
336 | double write_x = p.toPos.x + PositionShift.x;
337 | double write_y = p.toPos.y + PositionShift.y;
338 | Builder.BeginGLine(1, p.comment).
339 | AppendF("X", write_x).AppendF("Y", write_y);
340 |
341 | if (OmitDuplicateZ == false || MathUtil.EpsilonEqual(p.toPos.z, currentPos.z, MoveEpsilon) == false) {
342 | Builder.AppendF("Z", p.toPos.z);
343 | }
344 | if (OmitDuplicateF == false || MathUtil.EpsilonEqual(p.feedRate, currentFeed, MoveEpsilon) == false) {
345 | Builder.AppendF("F", p.feedRate);
346 | }
347 | if (OmitDuplicateE == false || MathUtil.EpsilonEqual(p.extruderA, extruderA, MoveEpsilon) == false) {
348 | Builder.AppendF(p.extrudeChar.ToString(), p.extruderA);
349 | }
350 |
351 | currentPos = p.toPos;
352 | currentFeed = p.feedRate;
353 | extruderA = p.extruderA;
354 | }
355 |
356 | // push point onto queue and update accumulated length
357 | protected virtual void append_to_queue(QueuedExtrude p)
358 | {
359 | double dt = (next_queue_index == 0) ?
360 | currentPos.xy.Distance(p.toPos.xy) : extrude_queue[next_queue_index-1].toPos.xy.Distance(p.toPos.xy);
361 | extrude_queue_len += dt;
362 |
363 | extrude_queue[next_queue_index] = p;
364 | next_queue_index = Math.Min(next_queue_index + 1, extrude_queue.Length - 1); ;
365 | }
366 |
367 | // emit point at end of queue and clear it
368 | protected virtual void flush_extrude_queue()
369 | {
370 | if (next_queue_index > 0) {
371 | emit_extrude(extrude_queue[next_queue_index - 1]);
372 | next_queue_index = 0;
373 | }
374 | extrude_queue_len = 0;
375 | }
376 |
377 |
378 |
379 | /*
380 | * Assembler API that Compiler uses
381 | */
382 |
383 |
384 | public virtual void AppendMoveTo(double x, double y, double z, double f, string comment = null)
385 | {
386 | queue_travel(new Vector3d(x, y, z), f, comment);
387 | }
388 | public virtual void AppendMoveTo(Vector3d pos, double f, string comment = null)
389 | {
390 | AppendMoveTo(pos.x, pos.y, pos.z, f, comment);
391 | }
392 |
393 |
394 |
395 | public virtual void AppendExtrudeTo(Vector3d pos, double feedRate, double extrudeDist, string comment = null)
396 | {
397 | if (ExtrudeParam == ExtrudeParamType.ExtrudeParamA)
398 | AppendMoveToA(pos, feedRate, extrudeDist, comment);
399 | else
400 | AppendMoveToE(pos, feedRate, extrudeDist, comment);
401 | }
402 |
403 |
404 | protected virtual void AppendMoveToE(double x, double y, double z, double f, double e, string comment = null)
405 | {
406 | queue_extrude(new Vector3d(x, y, z), f, e, 'E', comment, false);
407 | }
408 | protected virtual void AppendMoveToE(Vector3d pos, double f, double e, string comment = null)
409 | {
410 | AppendMoveToE(pos.x, pos.y, pos.z, f, e, comment);
411 | }
412 |
413 |
414 | protected virtual void AppendMoveToA(double x, double y, double z, double f, double a, string comment = null)
415 | {
416 | queue_extrude(new Vector3d(x, y, z), f, a, 'A', comment, false);
417 | }
418 | protected virtual void AppendMoveToA(Vector3d pos, double f, double a, string comment = null)
419 | {
420 | AppendMoveToA(pos.x, pos.y, pos.z, f, a, comment);
421 | }
422 |
423 |
424 |
425 | public virtual void BeginRetractRelativeDist(Vector3d pos, double feedRate, double extrudeDelta, string comment = null)
426 | {
427 | BeginRetract(pos, feedRate, ExtruderA + extrudeDelta, comment);
428 | }
429 | public virtual void BeginRetract(Vector3d pos, double feedRate, double extrudeDist, string comment = null) {
430 | if (in_retract)
431 | throw new Exception("BaseDepositionAssembler.BeginRetract: already in retract!");
432 | if (extrudeDist > extruderA)
433 | throw new Exception("BaseDepositionAssembler.BeginRetract: retract extrudeA is forward motion!");
434 |
435 | // need to flush any pending extrudes here, so that extruderA is at actual last extrude value
436 | flush_extrude_queue();
437 | retractA = extruderA;
438 | queue_extrude_to(pos, feedRate, extrudeDist, (comment == null) ? "Retract" : comment, true);
439 | in_retract = true;
440 | }
441 |
442 |
443 | public virtual void EndRetract(Vector3d pos, double feedRate, double extrudeDist = -9999, string comment = null) {
444 | if (! in_retract)
445 | throw new Exception("BaseDepositionAssembler.EndRetract: already in retract!");
446 | if (extrudeDist != -9999 && MathUtil.EpsilonEqual(extrudeDist, retractA, 0.0001) == false )
447 | throw new Exception("BaseDepositionAssembler.EndRetract: restart position is not same as start of retract!");
448 | if (extrudeDist == -9999)
449 | extrudeDist = retractA;
450 | queue_extrude_to(pos, feedRate, extrudeDist, (comment == null) ? "End Retract" : comment, true);
451 | in_retract = false;
452 | }
453 |
454 |
455 | public virtual void BeginTravel() {
456 | if (in_travel)
457 | throw new Exception("BaseDepositionAssembler.BeginTravel: already in travel!");
458 | in_travel = true;
459 | }
460 |
461 |
462 | public virtual void EndTravel()
463 | {
464 | if (in_travel == false)
465 | throw new Exception("BaseDepositionAssembler.EndTravel: not in travel!");
466 | in_travel = false;
467 | }
468 |
469 |
470 | public virtual void AppendTravelTo(double x, double y, double z, double f)
471 | {
472 | throw new NotImplementedException("BaseDepositionAssembler.AppendTravelTo");
473 | }
474 |
475 |
476 | public virtual void AppendComment(string comment)
477 | {
478 | Builder.AddCommentLine(comment);
479 | }
480 |
481 |
482 | public virtual void AppendDwell(int milliseconds, string comment = null)
483 | {
484 | flush_extrude_queue();
485 |
486 | Builder.BeginGLine(4, (comment != null) ? comment : "dwell" )
487 | .AppendI("P", milliseconds);
488 | }
489 |
490 |
491 | public virtual void AppendResetExtrudedLength()
492 | {
493 | if (in_retract)
494 | throw new Exception("BaseDepositionAssembler.AppendResetExtrudedLength: cannot reset during retract!");
495 | flush_extrude_queue();
496 | Builder.BeginGLine(92, "reset extruded length").AppendI("E", 0);
497 | extruderA = 0;
498 | }
499 |
500 |
501 | ///
502 | /// Assembler may internally queue up a series of points, to optimize gcode emission.
503 | /// Call this to ensure that everything is written out to GCodeBuilder
504 | ///
505 | public virtual void FlushQueues()
506 | {
507 | flush_extrude_queue();
508 | }
509 |
510 |
511 |
512 |
513 | protected virtual void AddStandardHeader(SingleMaterialFFFSettings Settings)
514 | {
515 | Builder.AddCommentLine("; Generated on " + DateTime.Now.ToLongDateString() + " by Gradientspace gsSlicer");
516 | Builder.AddCommentLine(string.Format("; Printer: {0} {1}", Settings.Machine.ManufacturerName, Settings.Machine.ModelIdentifier));
517 | Builder.AddCommentLine("; Print Settings");
518 | Builder.AddCommentLine("; Layer Height: " + Settings.LayerHeightMM);
519 | Builder.AddCommentLine("; Nozzle Diameter: " + Settings.Machine.NozzleDiamMM + " Filament Diameter: " + Settings.Machine.FilamentDiamMM);
520 | Builder.AddCommentLine("; Extruder Temp: " + Settings.ExtruderTempC);
521 | Builder.AddCommentLine(string.Format("; Speeds Extrude: {0} Travel: {1} Z: {2}", Settings.RapidExtrudeSpeed, Settings.RapidTravelSpeed, Settings.ZTravelSpeed));
522 | Builder.AddCommentLine(string.Format("; Retract Distance: {0} Speed: {1}", Settings.RetractDistanceMM, Settings.RetractSpeed));
523 | Builder.AddCommentLine(string.Format("; Shells: {0} InteriorShells: {1}", Settings.Shells, Settings.InteriorSolidRegionShells));
524 | Builder.AddCommentLine(string.Format("; RoofLayers: {0} FloorLayers: {1}", Settings.RoofLayers, Settings.FloorLayers));
525 | Builder.AddCommentLine(string.Format("; InfillX: {0}", Settings.SparseLinearInfillStepX));
526 | Builder.AddCommentLine(string.Format("; Support: {0} Angle {1} SpacingX: {2} Shell: {3} Gap: {4} VolScale: {5}",
527 | Settings.GenerateSupport, Settings.SupportOverhangAngleDeg, Settings.SupportSpacingStepX, Settings.EnableSupportShell, Settings.SupportSolidSpace, Settings.SupportVolumeScale));
528 | Builder.AddCommentLine(string.Format("; ClipOverlaps: {0} Tolerance: {1}", Settings.ClipSelfOverlaps, Settings.SelfOverlapToleranceX));
529 | Builder.AddCommentLine(string.Format("; LayerRange: {0}-{1}", Settings.LayerRangeFilter.a, Settings.LayerRangeFilter.b));
530 | }
531 |
532 |
533 |
534 |
535 |
536 |
537 | protected virtual void AddPrimeLine(SingleMaterialFFFSettings Settings)
538 | {
539 | Builder.AddCommentLine("---begin prime type=line");
540 |
541 | // extruder prime by drawing line across front of bed
542 | double PrimeHeight = Settings.Machine.MaxLayerHeightMM;
543 | double PrimeWidth = 2 * Settings.Machine.NozzleDiamMM;
544 |
545 | // assumes origin is at center of bed...
546 | Vector3d frontRight = new Vector3d(Settings.Machine.BedSizeXMM / 2, -Settings.Machine.BedSizeYMM / 2, PrimeHeight);
547 | frontRight.x -= 10;
548 | frontRight.y += 5;
549 | Vector3d frontLeft = frontRight; frontLeft.x = -frontRight.x;
550 |
551 | double primeLen = frontRight.Distance(frontLeft);
552 |
553 | double PrimeFeedRate = 1800;
554 | double prime_feed_len = AssemblerUtil.CalculateExtrudedFilament(
555 | PrimeWidth, PrimeHeight, primeLen, Settings.Machine.FilamentDiamMM);
556 |
557 | Builder.BeginGLine(92, "reset extruded length").AppendI("E", 0);
558 | BeginTravel();
559 | AppendMoveTo(frontRight, 9000, "start prime");
560 | EndTravel();
561 | AppendExtrudeTo(frontLeft, PrimeFeedRate, prime_feed_len, "extrude prime");
562 |
563 | AppendResetExtrudedLength();
564 |
565 | Builder.AddCommentLine("---end prime");
566 | }
567 |
568 |
569 |
570 |
571 | }
572 |
573 |
574 | }
--------------------------------------------------------------------------------