diff --git a/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs b/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs index ee97cf9c8..85d6f6e8f 100644 --- a/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs +++ b/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs @@ -42,10 +42,13 @@ namespace MatterHackers.MatterControl.DesignTools AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer); } - public interface ICustomEditorDraw : IEditorDraw + public interface IEditorDrawControled : IEditorDraw + { + bool DoEditorDraw(bool isSelected); + } + + public interface ICustomEditorDraw : IEditorDrawControled { void AddEditorTransparents(Object3DControlsLayer object3DControlLayer, List transparentMeshes, DrawEventArgs e); - - bool DoEditorDraw(bool isSelected); } } \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Primitives/SendGCodeObject3D.cs b/MatterControlLib/DesignTools/Primitives/SendGCodeObject3D.cs new file mode 100644 index 000000000..84224db1e --- /dev/null +++ b/MatterControlLib/DesignTools/Primitives/SendGCodeObject3D.cs @@ -0,0 +1,209 @@ +/* +Copyright (c) 2019, 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.Threading.Tasks; +using MatterControl.Printing; +using MatterHackers.Agg; +using MatterHackers.Agg.Font; +using MatterHackers.Agg.Image; +using MatterHackers.Agg.UI; +using MatterHackers.Agg.VertexSource; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.PartPreviewWindow; +using MatterHackers.PolygonMesh; +using MatterHackers.PolygonMesh.Processors; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class SendGCodeObject3D : Object3D, IObject3DControlsProvider, IGCodeTransformer, IEditorDrawControled + { + private bool hasBeenReached; + private double accumulatedLayerHeight; + + public SendGCodeObject3D() + { + Name = "Send G-Code".Localize(); + Color = Color.White.WithAlpha(.4); + Mesh = new RoundedRect(-20, -20, 20, 20, 3) + { + ResolutionScale = 10 + }.Extrude(.2); + } + + public static async Task Create() + { + var item = new SendGCodeObject3D(); + await item.Rebuild(); + return item; + } + + public string GCodeToSend { get; set; } = ""; + + public override bool Printable => 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)) + { + } + } + + Invalidate(InvalidateType.DisplayValues); + + UpdateTexture(); + + this.CancelAllParentBuilding(); + Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); + return Task.CompletedTask; + } + + private (string gcode, double worldZ) displayInfo = ("", double.MinValue); + + private double WorldZ => default(Vector3).Transform(this.WorldMatrix()).Z; + + 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; + if (accumulatedLayerHeight > WorldZ) + { + hasBeenReached = true; + yield return $"{GCodeToSend} ; G-Code from Scene Object"; + } + } + } + } + + public void Reset() + { + hasBeenReached = false; + accumulatedLayerHeight = 0; + } + + + public void DrawEditor(Object3DControlsLayer object3DControlLayer, DrawEventArgs e) + { + if (displayInfo.worldZ != WorldZ + || displayInfo.gcode != DisplayGCode) + { + UpdateTexture(); + } + } + + private string DisplayGCode + { + get + { + var max40Chars = GCodeToSend; + if (GCodeToSend.Length > 35) + { + max40Chars = GCodeToSend.Substring(0, 35) + "..."; + } + EnglishTextWrapping wrapper = new EnglishTextWrapping(10); + max40Chars = wrapper.InsertCRs(max40Chars, 120); + return max40Chars; + } + } + + private void UpdateTexture() + { + Mesh.FaceTextures.Clear(); + displayInfo.worldZ = WorldZ; + displayInfo.gcode = DisplayGCode; + var theme = AppContext.Theme; + var texture = new ImageBuffer(128, 128, 32); + var graphics2D = texture.NewGraphics2D(); + graphics2D.Clear(theme.BackgroundColor); + graphics2D.DrawString($"Height: {displayInfo.worldZ:0.##}", + texture.Width / 2, + texture.Height * .7, + 14, + Agg.Font.Justification.Center, + Agg.Font.Baseline.BoundsCenter, + theme.TextColor); + graphics2D.DrawString($"G-Code", + texture.Width / 2, + texture.Height * .45, + 14, + Agg.Font.Justification.Center, + Agg.Font.Baseline.BoundsCenter, + theme.TextColor); + var height = texture.Height * .37; + graphics2D.Line(texture.Width / 5, height, texture.Width / 5 * 4, height, theme.TextColor); + graphics2D.DrawString($"{displayInfo.gcode}", + texture.Width / 2, + texture.Height * .3, + 10, + Agg.Font.Justification.Center, + Agg.Font.Baseline.BoundsCenter, + theme.TextColor); + Mesh.PlaceTextureOnFaces(0, texture); + } + + public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer) + { + return AxisAlignedBoundingBox.Empty(); + } + + public bool DoEditorDraw(bool isSelected) + { + return true; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs b/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs index 9db9a76ad..436bed2ca 100644 --- a/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/SetTemperatureObject3D.cs @@ -43,7 +43,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools { - public class SetTemperatureObject3D : Object3D, IObject3DControlsProvider, IGCodeTransformer, IEditorDraw + public class SetTemperatureObject3D : Object3D, IObject3DControlsProvider, IGCodeTransformer, IEditorDrawControled { private bool hasBeenReached; private double accumulatedLayerHeight; @@ -178,5 +178,10 @@ namespace MatterHackers.MatterControl.DesignTools { return AxisAlignedBoundingBox.Empty(); } + + public bool DoEditorDraw(bool isSelected) + { + return true; + } } } \ No newline at end of file diff --git a/MatterControlLib/Library/Providers/MatterControl/CalibrationPartsContainer.cs b/MatterControlLib/Library/Providers/MatterControl/CalibrationPartsContainer.cs index 865ab6ea9..77e5a3244 100644 --- a/MatterControlLib/Library/Providers/MatterControl/CalibrationPartsContainer.cs +++ b/MatterControlLib/Library/Providers/MatterControl/CalibrationPartsContainer.cs @@ -39,7 +39,7 @@ using MatterHackers.MatterControl.DesignTools; namespace MatterHackers.MatterControl.Library { - public class CalibrationPartsContainer : LibraryContainer + public class CalibrationPartsContainer : LibraryContainer { public CalibrationPartsContainer() { @@ -53,13 +53,6 @@ namespace MatterHackers.MatterControl.Library var oemParts = StaticData.Instance.GetFiles(Path.Combine("OEMSettings", "SampleParts")); Items = new SafeList(oemParts.Select(s => new StaticDataItem(s))); - Items.Add(new GeneratorItem( - "Set Temperature".Localize(), - async () => await SetTemperatureObject3D.Create()) - { - Category = this.Name - }); - Items.Add(new GeneratorItem( "PLA Temperature Tower".Localize(), async () => await TemperatureTowerObject3D.Create(220)) diff --git a/MatterControlLib/Library/Providers/MatterControl/DesignAppsCollectionContainer.cs b/MatterControlLib/Library/Providers/MatterControl/DesignAppsCollectionContainer.cs index 3bdd672b9..52b5d0c91 100644 --- a/MatterControlLib/Library/Providers/MatterControl/DesignAppsCollectionContainer.cs +++ b/MatterControlLib/Library/Providers/MatterControl/DesignAppsCollectionContainer.cs @@ -56,6 +56,16 @@ namespace MatterHackers.MatterControl.Library IsReadOnly = true }); + this.ChildContainers.Add( + new DynamicContainerLink( + "Scripting".Localize(), + StaticData.Instance.LoadIcon(Path.Combine("Library", "folder.png")), + StaticData.Instance.LoadIcon(Path.Combine("Library", "scripting_icon.png")), + () => new ScriptingPartsContainer()) + { + IsReadOnly = true + }); + this.ChildContainers.Add( new DynamicContainerLink( "Primitives".Localize(), diff --git a/MatterControlLib/Library/Providers/MatterControl/ScriptingPartsContainer.cs b/MatterControlLib/Library/Providers/MatterControl/ScriptingPartsContainer.cs new file mode 100644 index 000000000..08f1477da --- /dev/null +++ b/MatterControlLib/Library/Providers/MatterControl/ScriptingPartsContainer.cs @@ -0,0 +1,124 @@ +/* +Copyright (c) 2019, John Lewin +Copyright (c) 2021, 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; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Agg.Platform; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.DesignTools; + +namespace MatterHackers.MatterControl.Library +{ + public class ScriptingPartsContainer : LibraryContainer + { + public ScriptingPartsContainer() + { + this.ChildContainers = new SafeList(); + this.Items = new SafeList(); + this.Name = "Scripting".Localize(); + } + + public override void Load() + { + Items = new SafeList(); + + Items.Add(new GeneratorItem( + "Set Temperature".Localize(), + async () => await SetTemperatureObject3D.Create()) + { + Category = this.Name + }); + + Items.Add(new GeneratorItem( + "Send G-Code".Localize(), + async () => await SendGCodeObject3D.Create()) + { + Category = this.Name + }); + } + + private class StaticDataItem : ILibraryAssetStream + { + public StaticDataItem() + { + } + + public StaticDataItem(string relativePath) + { + this.AssetPath = relativePath; + } + + public string FileName => Path.GetFileName(AssetPath); + + public string ContentType => Path.GetExtension(AssetPath).ToLower().Trim('.'); + + public string AssetPath { get; } + + public long FileSize { get; } = -1; + + public bool LocalContentExists => true; + + public string Category { get; } = ""; + + public string ID => agg_basics.GetLongHashCode(AssetPath).ToString(); + + public event EventHandler NameChanged; + + public string Name + { + get => this.FileName; + set + { + // do nothing (can't rename) + } + } + + public bool IsProtected => true; + + public bool IsVisible => true; + + public DateTime DateModified { get; } = DateTime.Now; + + public DateTime DateCreated { get; } = DateTime.Now; + + public Task GetStream(Action progress) + { + return Task.FromResult(new StreamAndLength() + { + Stream = StaticData.Instance.OpenStream(AssetPath), + Length = -1 + }); + } + } + } +} diff --git a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs index 5713b9559..1f0e7ee66 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs @@ -1088,7 +1088,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - foreach (var item in scene.Descendants().Where(i => i is ICustomEditorDraw customEditorDraw1 && customEditorDraw1.DoEditorDraw(i == selectedItem))) + foreach (var item in scene.Descendants().Where(i => i is IEditorDrawControled customEditorDraw1 && customEditorDraw1.DoEditorDraw(i == selectedItem))) { editorDrawItems.Add(item); } diff --git a/StaticData/Icons/Library/scripting_icon.png b/StaticData/Icons/Library/scripting_icon.png new file mode 100644 index 000000000..e65879721 Binary files /dev/null and b/StaticData/Icons/Library/scripting_icon.png differ diff --git a/StaticData/Images/Thumbnails/11842437371347377518-256x256.png b/StaticData/Images/Thumbnails/11842437371347377518-256x256.png new file mode 100644 index 000000000..46a4bbf97 Binary files /dev/null and b/StaticData/Images/Thumbnails/11842437371347377518-256x256.png differ diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index a366998b7..580461830 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -1984,6 +1984,9 @@ Translated:Fuzzy Frequency English:Fuzzy Thickness Translated:Fuzzy Thickness +English:G Code To Send +Translated:G Code To Send + English:G Key Translated:G Key @@ -4369,6 +4372,9 @@ Translated:Scale Offset English:Scale Type Translated:Scale Type +English:Scripting +Translated:Scripting + English:SD Card Translated:SD Card @@ -4459,6 +4465,9 @@ Translated:Send English:Send email notifications Translated:Send email notifications +English:Send G-Code +Translated:Send G-Code + English:Send SMS notifications Translated:Send SMS notifications diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index b2b6261e0..cce755cd9 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit b2b6261e0936f91a9f018da860c636dfafef2d91 +Subproject commit cce755cd9c356a96edb641ed515113caa6bf6ad3 diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 238b25271..d82343531 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 238b25271497943ece9ab855b119810abe2c9809 +Subproject commit d8234353154f15256cf785d9665bdc8f5636eee9