diff --git a/MatterControlLib/DesignTools/Interfaces/IGCodeTransformer.cs b/MatterControlLib/DesignTools/Interfaces/IGCodeTransformer.cs new file mode 100644 index 000000000..e69a387b1 --- /dev/null +++ b/MatterControlLib/DesignTools/Interfaces/IGCodeTransformer.cs @@ -0,0 +1,40 @@ +/* +Copyright (c) 2018, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; + +namespace MatterHackers.MatterControl.DesignTools +{ + public interface IGCodeTransformer + { + IEnumerable ProcessCGcode(string lineToWrite, PrinterConfig printer); + + void Reset(); + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs b/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs index e55300dbf..0b8b6063b 100644 --- a/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs @@ -49,6 +49,7 @@ namespace MatterHackers.MatterControl.DesignTools } public override string ThumbnailName => "Cylinder"; + public CylinderObject3D(double diameter, double height, int sides) : this() { diff --git a/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs b/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs new file mode 100644 index 000000000..b0cba58e6 --- /dev/null +++ b/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs @@ -0,0 +1,124 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; +using System.Threading.Tasks; +using MatterControl.Printing; +using MatterHackers.Agg; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.PartPreviewWindow; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class SetTemperatureObject3D : Object3D, IObject3DControlsProvider, IGCodeTransformer + { + private bool hasBeenReached; + private double accumulatedLayerHeight; + + public SetTemperatureObject3D() + { + Name = "Set Temperature".Localize(); + Color = new Color(.11, .98, .26, .2); + Mesh = PlatonicSolids.CreateCube(40, 40, 0.2); + } + + public static async Task Create() + { + var item = new SetTemperatureObject3D(); + await item.Rebuild(); + return item; + } + + public double Temperature { get; set; } = 210; + + public override bool Persistable => false; + + public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) + { + object3DControlsLayer.AddControls(ControlTypes.MoveInZ | ControlTypes.Shadow | ControlTypes.ScaleMatrixXY); + } + + public override async void OnInvalidate(InvalidateArgs invalidateType) + { + if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) + && invalidateType.Source == this) + { + await Rebuild(); + } + else + { + base.OnInvalidate(invalidateType); + } + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + + using (RebuildLock()) + { + using (new CenterAndHeightMaintainer(this)) + { + } + } + + Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); + return Task.CompletedTask; + } + + public IEnumerable ProcessCGcode(string lineToWrite, PrinterConfig printer) + { + if (!hasBeenReached + && lineToWrite.StartsWith("; LAYER_HEIGHT:")) + { + double layerHeight = 0; + if (GCodeFile.GetFirstNumberAfter("; LAYER_HEIGHT", lineToWrite, ref layerHeight, out _, stopCheckingString: ":")) + { + accumulatedLayerHeight += layerHeight; + var worldPosition = default(Vector3); + worldPosition = worldPosition.Transform(this.WorldMatrix()); + if (accumulatedLayerHeight > worldPosition.Z) + { + hasBeenReached = true; + yield return $"M104 S{Temperature} ; Change Layer Temperature"; + } + } + } + } + + public void Reset() + { + hasBeenReached = false; + accumulatedLayerHeight = 0; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/Library/Export/GCodeExport.cs b/MatterControlLib/Library/Export/GCodeExport.cs index e9ff47d85..0af32641d 100644 --- a/MatterControlLib/Library/Export/GCodeExport.cs +++ b/MatterControlLib/Library/Export/GCodeExport.cs @@ -334,6 +334,8 @@ namespace MatterHackers.MatterControl.Library.Export accumulatedStream = new ProcessWriteRegexStream(printer, accumulatedStream, queuedCommandStream); + accumulatedStream = new RunSceneGCodeProcesorsStream(printer, accumulatedStream, queuedCommandStream); + return accumulatedStream; } diff --git a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs index 1c83e431d..503b62ade 100644 --- a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs +++ b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs @@ -116,6 +116,10 @@ namespace MatterHackers.MatterControl.Library () => "SCAD Script".Localize(), async () => await OpenScadScriptObject3D.Create()) { DateCreated = new System.DateTime(index++) }, + new GeneratorItem( + () => "Set Temperature".Localize(), + async () => await SetTemperatureObject3D.Create()) + { DateCreated = new System.DateTime(index++) }, #endif new GeneratorItem( () => "Image Converter".Localize(), diff --git a/MatterControlLib/PartPreviewWindow/SceneViewer/SelectedItemDrawable.cs b/MatterControlLib/PartPreviewWindow/SceneViewer/SelectedItemDrawable.cs index 4564107cf..d20889044 100644 --- a/MatterControlLib/PartPreviewWindow/SceneViewer/SelectedItemDrawable.cs +++ b/MatterControlLib/PartPreviewWindow/SceneViewer/SelectedItemDrawable.cs @@ -99,7 +99,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow guiWidget.Invalidate(); } - this.RenderSelection(item, selectionColor, world); + this.RenderSelection(item, selectionColor.WithAlpha(item.Color.Alpha0To255), world); } } diff --git a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs index 19334c2bb..f404bd237 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs @@ -59,6 +59,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow ScaleMatrixXY = 16, Shadow = 32, SnappingIndicators = 64, + ScaleHeight = 128, Standard2D = MoveInZ | Shadow | SnappingIndicators | RotateZ | ScaleMatrixXY } @@ -219,6 +220,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow Object3DControls.Add(new MoveInZControl(this)); } + if (controls.HasFlag(ControlTypes.ScaleHeight)) + { + Object3DControls.Add(new ScaleHeightControl(this)); + } + if (controls.HasFlag(ControlTypes.ScaleMatrixXY)) { Object3DControls.Add(new ScaleCornerControl(this, 0)); diff --git a/MatterControlLib/PrinterCommunication/Io/ProcessWriteRegExStream.cs b/MatterControlLib/PrinterCommunication/Io/ProcessWriteRegExStream.cs index 1c4640171..c387c0b64 100644 --- a/MatterControlLib/PrinterCommunication/Io/ProcessWriteRegExStream.cs +++ b/MatterControlLib/PrinterCommunication/Io/ProcessWriteRegExStream.cs @@ -35,9 +35,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { public class ProcessWriteRegexStream : GCodeStreamProxy { - private PrinterMove currentMove = PrinterMove.Unknown; - - public static Regex GetQuotedParts = new Regex(@"([""'])(\\?.)*?\1", RegexOptions.Compiled); + public static Regex GetQuotedParts { get; } = new Regex(@"([""'])(\\?.)*?\1", RegexOptions.Compiled); private QueuedCommandsStream queueStream; @@ -78,31 +76,15 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io var lineToSend = lines[0]; - if (lineToSend != null - && LineIsMovement(lineToSend)) - { - currentMove = GetPosition(lineToSend, currentMove); - } - - // is it a position set? - if (lineToSend.StartsWith("G92")) - { - GCodeFile.GetFirstNumberAfter("X", lineToSend, ref this.currentMove.position.X); - GCodeFile.GetFirstNumberAfter("Y", lineToSend, ref this.currentMove.position.Y); - GCodeFile.GetFirstNumberAfter("Z", lineToSend, ref this.currentMove.position.Z); - GCodeFile.GetFirstNumberAfter("E", lineToSend, ref this.currentMove.extrusion); - - // tell the stream pipeline what the actual printer position is - this.SetPrinterPosition(this.currentMove); - } - return lineToSend; } public static List ProcessWriteRegEx(string lineToWrite, PrinterConfig printer) { - var linesToWrite = new List(); - linesToWrite.Add(lineToWrite); + var linesToWrite = new List + { + lineToWrite + }; var addedLines = new List(); for (int i = 0; i < linesToWrite.Count; i++) @@ -122,6 +104,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io { addedLines.Add(splitReplacement[j]); } + break; } } @@ -132,11 +115,5 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io return linesToWrite; } - - public override void SetPrinterPosition(PrinterMove position) - { - this.currentMove.CopyKnowSettings(position); - internalStream.SetPrinterPosition(currentMove); - } } } \ No newline at end of file diff --git a/MatterControlLib/PrinterCommunication/Io/RunSceneGCodeProcesorsStream.cs b/MatterControlLib/PrinterCommunication/Io/RunSceneGCodeProcesorsStream.cs new file mode 100644 index 000000000..c526a2441 --- /dev/null +++ b/MatterControlLib/PrinterCommunication/Io/RunSceneGCodeProcesorsStream.cs @@ -0,0 +1,111 @@ +/* +Copyright (c) 2015, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using MatterControl.Printing; +using MatterHackers.DataConverters3D; +using MatterHackers.MatterControl.DesignTools; + +namespace MatterHackers.MatterControl.PrinterCommunication.Io +{ + + public class RunSceneGCodeProcesorsStream : GCodeStreamProxy + { + private QueuedCommandsStream queueStream; + private List gcodeTransformers; + + public override string DebugInfo => ""; + + public RunSceneGCodeProcesorsStream(PrinterConfig printer, GCodeStream internalStream, QueuedCommandsStream queueStream) + : base(printer, internalStream) + { + this.queueStream = queueStream; + + // get all the gcode processors that are in the scene + gcodeTransformers = printer.Bed.Scene.Descendants().Where(i => i is IGCodeTransformer).Select(i => (IGCodeTransformer)i).ToList(); + + foreach (var gcodeTransformer in gcodeTransformers) + { + gcodeTransformer.Reset(); + } + } + + public override string ReadLine() + { + var baseLine = base.ReadLine(); + + if (baseLine == null) + { + return null; + } + + if (baseLine.EndsWith("; NO_PROCESSING")) + { + return baseLine; + } + + // if we are not printing or the line has no content don't process it + if (baseLine.Length == 0 + || baseLine.Trim().Length == 0) + { + return baseLine; + } + + var lines = ProcessGCodeLine(baseLine, printer); + for (int i = lines.Count - 1; i >= 1; i--) + { + queueStream.Add(lines[i], true); + } + + var lineToSend = lines[0]; + + return lineToSend; + } + + private List ProcessGCodeLine(string lineToWrite, PrinterConfig printer) + { + var linesToWrite = new List + { + lineToWrite + }; + + var addedLines = new List(); + foreach (var gcodeTransformer in gcodeTransformers) + { + addedLines.AddRange(gcodeTransformer.ProcessCGcode(lineToWrite, printer)); + } + + linesToWrite.AddRange(addedLines); + + return linesToWrite; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 7ea195631..3e05b7605 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -2431,6 +2431,8 @@ Make sure that your printer is turned on. Some printers will appear to be connec processWriteRegexStream = new ProcessWriteRegexStream(Printer, accumulatedStream, queuedCommandStream); accumulatedStream = processWriteRegexStream; + accumulatedStream = new RunSceneGCodeProcesorsStream(Printer, accumulatedStream, queuedCommandStream); + totalGCodeStream = accumulatedStream; // Force a reset of the printer checksum state (but allow it to be write regexed)