Fixed the tool speed stream to change while printing

Made it possible to visualize the emulator as it is printing
fixing warnings
issue: MatterHackers/MCCentral#5432
Dual Extrusion speed not matching settings
This commit is contained in:
Lars Brubaker 2019-05-02 18:06:28 -07:00
parent ff477d9c0e
commit 2c74f07572
5 changed files with 108 additions and 77 deletions

View file

@ -43,6 +43,7 @@ using MatterHackers.MatterControl.PartPreviewWindow.View3D;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.MeshVisualizer;
using MatterHackers.PolygonMesh;
using MatterHackers.PrinterEmulator;
using MatterHackers.RenderOpenGl;
using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath;
@ -68,6 +69,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private List<IDrawable> drawables = new List<IDrawable>();
private List<IDrawableItem> itemDrawables = new List<IDrawableItem>();
private Vector3 lastEmulatorPosition;
public bool AllowBedRenderingWhenEmpty { get; set; }
@ -143,7 +145,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
@ -186,7 +188,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
AxisAlignedBoundingBox bounds = child.TraceData().GetAxisAlignedBoundingBox();
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
for(int i=0; i<4; i++)
for (int i = 0; i < 4; i++)
{
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
@ -196,7 +198,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
@ -213,12 +215,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
foreach (var item in object3D.VisibleMeshes())
{
// check for correct persistable rendering
if(InteractionLayer.ViewOnlyTexture != null
if (InteractionLayer.ViewOnlyTexture != null
&& item.Mesh.Faces.Count > 0)
{
ImageBuffer faceTexture = null;
//item.Mesh.FaceTexture.TryGetValue((item.Mesh.Faces[0], 0), out faceTexture);
// item.Mesh.FaceTexture.TryGetValue((item.Mesh.Faces[0], 0), out faceTexture);
bool hasPersistableTexture = faceTexture == InteractionLayer.ViewOnlyTexture;
if (item.WorldPersistable())
@ -256,7 +258,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
item.WorldMatrix(),
sceneContext.ViewState.RenderType,
item.WorldMatrix() * World.ModelviewMatrix,
darkWireframe, () => Invalidate());
darkWireframe,
() => Invalidate());
}
else if (drawColor != Color.Transparent)
{
@ -269,7 +272,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|| selectedItem.Parents<ModifiedMeshObject3D>().Any((mw) => mw == item));
// Invoke all item Drawables
foreach(var drawable in itemDrawables.Where(d => d.DrawStage != DrawStage.Last && d.Enabled))
foreach (var drawable in itemDrawables.Where(d => d.DrawStage != DrawStage.Last && d.Enabled))
{
drawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
}
@ -326,7 +329,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
// Validate against active hotends
foreach(var hotendIndex in activeHotends)
foreach (var hotendIndex in activeHotends)
{
var hotendBounds = printer.Settings.ToolBounds[hotendIndex];
if (!hotendBounds.Contains(itemBounds))
@ -345,7 +348,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
if(drawColor.alpha != 255
if (drawColor.alpha != 255
&& item is Object3D item3D)
{
item3D.EnsureTransparentSorting();
@ -378,7 +381,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return drawColor;
}
public enum EditorType { Printer, Part }
public enum EditorType
{
Printer,
Part
}
public EditorType EditorMode { get; set; } = EditorType.Part;
@ -463,6 +470,23 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
if (sceneContext.Printer.Connection.SerialPort is Emulator emulator)
{
var matrix = Matrix4X4.CreateTranslation(emulator.CurrentPosition + new Vector3(.5, .5, 5));
GLHelper.Render(PlatonicSolids.CreateCube(1, 1, 10),
MaterialRendering.Color(emulator.ExtruderIndex),
matrix,
RenderTypes.Shaded,
matrix * World.ModelviewMatrix);
if (emulator.CurrentPosition != lastEmulatorPosition)
{
Invalidate();
}
lastEmulatorPosition = emulator.CurrentPosition;
}
transparentMeshes.Sort(BackToFrontXY);
var bedNormalInViewSpace = Vector3Ex.TransformNormal(Vector3.UnitZ, World.ModelviewMatrix).GetNormal();
@ -477,7 +501,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
var wireColor = Color.Transparent;
switch(modelRenderStyle)
switch (modelRenderStyle)
{
case ModelRenderStyle.Wireframe:
wireColor = darkWireframe;
@ -544,7 +568,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private void DrawInteractionVolumes(DrawEventArgs e)
{
if(SuppressUiVolumes)
if (SuppressUiVolumes)
{
return;
}

View file

@ -85,7 +85,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
public TrackballTumbleWidget TrackballTumbleWidget { get; private set;}
public TrackballTumbleWidget TrackballTumbleWidget { get; private set; }
public InteractionLayer InteractionLayer { get; }
@ -115,7 +115,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.theme = theme;
this.Name = "View3DWidget";
this.BackgroundColor = theme.BedBackgroundColor;
this.HAnchor = HAnchor.Stretch; // HAnchor.MaxFitOrStretch,
this.HAnchor = HAnchor.Stretch; // HAnchor.MaxFitOrStretch,
this.VAnchor = VAnchor.Stretch; // VAnchor.MaxFitOrStretch
viewControls3D.TransformStateChanged += ViewControls3D_TransformStateChanged;
@ -300,7 +300,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
HAnchor = HAnchor.Right | HAnchor.Fit,
VAnchor = VAnchor.Top | VAnchor.Fit,
//Margin = new BorderDouble(top: tumbleCubeControl.Height + tumbleCubeControl.Margin.Height + 2),
// Margin = new BorderDouble(top: tumbleCubeControl.Height + tumbleCubeControl.Margin.Height + 2),
BackgroundColor = theme.MinimalShade,
Name = "View Options Bar"
};
@ -400,7 +400,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var bounds = Scene.GetAxisAlignedBoundingBox();
if(bounds.XSize > 0)
if (bounds.XSize > 0)
{
zNear = double.PositiveInfinity;
zFar = double.NegativeInfinity;
@ -473,7 +473,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
bool invertIcons = ApplicationController.Instance.MenuTheme.InvertIcons;
// Build workspace actions, each having a unique ID
var actions = new []
var actions = new[]
{
new NamedAction()
{
@ -483,7 +483,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Action = this.PushToPrinterAndPrint,
IsEnabled = () => sceneContext.EditableScene
|| (sceneContext.EditContext.SourceItem is ILibraryAsset libraryAsset
&& string.Equals(Path.GetExtension(libraryAsset.FileName) ,".gcode" ,StringComparison.OrdinalIgnoreCase))
&& string.Equals(Path.GetExtension(libraryAsset.FileName), ".gcode", StringComparison.OrdinalIgnoreCase))
},
new NamedAction()
{
@ -524,7 +524,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Icon = AggContext.StaticData.LoadIcon("remove.png").SetPreMultiply(),
Title = "Remove".Localize(),
Action = sceneContext.Scene.DeleteSelection,
IsEnabled = () => sceneContext.Scene.SelectedItem != null
IsEnabled = () => sceneContext.Scene.SelectedItem != null
},
new NamedAction()
{
@ -534,13 +534,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Action = () =>
{
ApplicationController.Instance.ExportLibraryItems(
new[] { new InMemoryLibraryItem(sceneContext.Scene)},
new[] { new InMemoryLibraryItem(sceneContext.Scene) },
centerOnBed: false,
printer: printer);
},
IsEnabled = () => sceneContext.EditableScene
|| (sceneContext.EditContext.SourceItem is ILibraryAsset libraryAsset
&& string.Equals(Path.GetExtension(libraryAsset.FileName) ,".gcode" ,StringComparison.OrdinalIgnoreCase))
&& string.Equals(Path.GetExtension(libraryAsset.FileName), ".gcode", StringComparison.OrdinalIgnoreCase))
},
new NamedAction()
{
@ -618,7 +618,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private void ModelViewSidePanel_Resized(object sender, EventArgs e)
{
if (this.Printer !=null)
if (this.Printer != null)
{
this.Printer.ViewState.SelectedObjectPanelWidth = selectedObjectPanel.Width;
}
@ -626,7 +626,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private void UpdateRenderView(object sender, EventArgs e)
{
TrackballTumbleWidget.CenterOffsetX = -modelViewSidePanel.Width;
TrackballTumbleWidget.CenterOffsetX = -modelViewSidePanel.Width;
}
private void SceneContext_SceneLoaded(object sender, EventArgs e)
@ -1056,7 +1056,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (selectedItem != null)
{
//DrawTestToGl(graphics2D, selectedItem);
// DrawTestToGl(graphics2D, selectedItem);
}
}
@ -1318,7 +1318,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
IObject3D selectedItem = Scene.SelectedItem;
lastMouseMove = mouseEvent.Position;
if(lastMouseMove != mouseDownPositon)
if (lastMouseMove != mouseDownPositon)
{
mouseDownPositon = Vector2.Zero;
}
@ -1545,7 +1545,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
parents.Add(parent);
parent = parent.Parent;
}
Vector2 offset = new Vector2();
Vector2 offset = default(Vector2);
for (int i = parents.Count - 1; i >= 0; i--)
{
offset += parents[i].OriginRelativeParent;
@ -1630,7 +1630,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (object3D.TraceData().Contains(info.HitPosition))
{
CurrentSelectInfo.PlaneDownHitPos = info.HitPosition;
CurrentSelectInfo.LastMoveDelta = new Vector3();
CurrentSelectInfo.LastMoveDelta = default(Vector3);
selectedHitItem = object3D;
break;
}
@ -1640,7 +1640,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (selectedHitItem != null)
{
selectedItem.Children.Remove(selectedHitItem);
if(selectedItem.Children.Count == 0)
if (selectedItem.Children.Count == 0)
{
Scene.SelectedItem = null;
}
@ -1714,7 +1714,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
},
altBounds: new RectangleDouble(mouseEvent.X + 1, mouseEvent.Y + 1, mouseEvent.X + 1, mouseEvent.Y + 1));
var actions = new[] {
var actions = new[]
{
new ActionSeparator(),
WorkspaceActions["Cut"],
WorkspaceActions["Copy"],
@ -1723,7 +1724,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
new NamedAction()
{
Title = "Save As".Localize(),
Action = () => UiThread.RunOnIdle(() =>
Action = () => UiThread.RunOnIdle(() =>
{
DialogWindow.Show(
new SaveAsPage(
@ -1745,7 +1746,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}));
}),
IsEnabled = () => sceneContext.EditableScene
IsEnabled = () => sceneContext.EditableScene
},
new NamedAction()
{
@ -1755,7 +1756,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Action = () =>
{
ApplicationController.Instance.ExportLibraryItems(
new[]{ new InMemoryLibraryItem(selectedItem)},
new[] { new InMemoryLibraryItem(selectedItem) },
centerOnBed: false,
printer: printer);
}
@ -1786,7 +1787,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme);
var actions = new[] {
var actions = new[]
{
new ActionSeparator(),
new NamedAction()
{
@ -1940,7 +1942,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (object3D.TraceData().Contains(intersectionInfo.HitPosition))
{
CurrentSelectInfo.PlaneDownHitPos = intersectionInfo.HitPosition;
CurrentSelectInfo.LastMoveDelta = new Vector3();
CurrentSelectInfo.LastMoveDelta = default(Vector3);
return object3D;
}
}
@ -1971,11 +1973,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
sceneContext.World.Render3DLine(
drawCenter - new Vector3(-50, 0, 0),
drawCenter - new Vector3(50, 0, 0), drawColor, zBuffer, 2);
drawCenter - new Vector3(50, 0, 0),
drawColor,
zBuffer,
2);
sceneContext.World.Render3DLine(
drawCenter - new Vector3(0, -50, 0),
drawCenter - new Vector3(0, 50, 0), drawColor, zBuffer, 2);
drawCenter - new Vector3(0, 50, 0),
drawColor,
zBuffer,
2);
drawColor = Color.Black;
drawCenter.Z = 0;

View file

@ -33,7 +33,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.PrinterEmulator
{
public partial class Emulator : IFrostedSerialPort, IDisposable
public class Emulator : IFrostedSerialPort, IDisposable
{
/// <summary>
/// The number of seconds the emulator should take to heat up to a given target.
@ -122,17 +122,17 @@ namespace MatterHackers.PrinterEmulator
public bool SimulateLineErrors { get; set; } = false;
private Vector3 _position;
private Vector3 _destination;
public Vector3 Destination
{
get => _position;
get => _destination;
private set
{
if (value != _position)
if (value != _destination)
{
_position = value;
_destination = value;
DestinationChanged?.Invoke(null, null);
}
}
@ -235,7 +235,7 @@ namespace MatterHackers.PrinterEmulator
if (command.StartsWith("G0") || command.StartsWith("G1"))
{
var startPostion = CurrentPosition;
var timeToMove_ms = (long)((CurrentPosition - Destination).Length * FeedRate) * 1000;
var timeToMove_ms = (long)((CurrentPosition - Destination).Length / FeedRate * 1000.0 * 60.5);
var startTime_ms = UiThread.CurrentTimerMs;
var doneTime_ms = startTime_ms + timeToMove_ms;
// wait for the amount of time it takes to move the extruder
@ -344,9 +344,9 @@ namespace MatterHackers.PrinterEmulator
private string HomePosition(string command)
{
_position.X = 0;
_position.Y = 0;
_position.Z = 0;
_destination.X = 0;
_destination.Y = 0;
_destination.Z = 0;
return "ok\n";
}
@ -542,7 +542,7 @@ namespace MatterHackers.PrinterEmulator
private string ParseMovmentCommand(string command)
{
var newPosition = default(Vector3);
var newPosition = Destination;
GetFirstNumberAfter("X", command, ref newPosition.X);
GetFirstNumberAfter("Y", command, ref newPosition.Y);
GetFirstNumberAfter("Z", command, ref newPosition.Z);

View file

@ -47,8 +47,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
private void Settings_SettingChanged(object sender, StringEventArgs stringEvent)
{
// we don't change the setting while printing
if (stringEvent.Data == SettingsKey.t1_extrusion_move_speed_multiplier
&& !printer.Connection.Printing)
if (stringEvent.Data == SettingsKey.t1_extrusion_move_speed_multiplier)
{
t0Multiplier = printer.Settings.GetValue<double>(SettingsKey.t1_extrusion_move_speed_multiplier);
}

View file

@ -238,7 +238,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private readonly StartsWithLineActions readLineStartCallBacks = new StartsWithLineActions();
// we start out by setting it to a nothing file
private IFrostedSerialPort serialPort;
public IFrostedSerialPort SerialPort { get; private set; }
private double _targetBedTemperature;
@ -896,12 +896,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public void ReleaseAndReportFailedConnection(ConnectionFailure reason)
{
// Shutdown the serial port
if (serialPort != null)
if (SerialPort != null)
{
// Close and dispose the serial port
serialPort.Close();
serialPort.Dispose();
serialPort = null;
SerialPort.Close();
SerialPort.Dispose();
SerialPort = null;
}
// Notify
@ -1001,7 +1001,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
// we're actually doing the bulk of the connection time in CreateAndOpen
CommunicationState = CommunicationStates.AttemptingToConnect;
serialPort = portFactory.CreateAndOpen(serialPortName, Printer.Settings, baudRate, true);
SerialPort = portFactory.CreateAndOpen(serialPortName, Printer.Settings, baudRate, true);
#if __ANDROID__
ToggleHighLowHigh(serialPort);
#endif
@ -1021,10 +1021,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication
while (true)
{
// Plugins required probing to fill read buffer
var na = serialPort.BytesToRead;
var na = SerialPort.BytesToRead;
// Read, sanitize, store
string response = serialPort.ReadExisting().Replace("\r\n", "\n").Replace('\r', '\n');
string response = SerialPort.ReadExisting().Replace("\r\n", "\n").Replace('\r', '\n');
sb.Append(response);
bool hasNewline = response.Contains('\n');
@ -1189,13 +1189,13 @@ You will then need to logout and log back in to the computer for the changes to
CommunicationState = CommunicationStates.Disconnecting;
currentReadThreadIndex++;
if (serialPort != null)
if (SerialPort != null)
{
serialPort.Close();
serialPort.Dispose();
SerialPort.Close();
SerialPort.Dispose();
}
serialPort = null;
SerialPort = null;
}
else
{
@ -1490,7 +1490,7 @@ You will then need to logout and log back in to the computer for the changes to
{
// TODO: Ideally we would shutdown the printer connection when this method is called and we're connected. The
// current approach results in unpredictable behavior if the caller fails to close the connection
if (serialPort == null && this.Printer.Settings != null)
if (SerialPort == null && this.Printer.Settings != null)
{
IFrostedSerialPort resetSerialPort = FrostedSerialPortFactory.GetAppropriateFactory(this.DriverType).Create(this.ComPort, Printer.Settings);
resetSerialPort.Open();
@ -1511,7 +1511,7 @@ You will then need to logout and log back in to the computer for the changes to
timeSinceLastReadAnything.Restart();
// we want this while loop to be as fast as possible. Don't allow any significant work to happen in here
while (CommunicationState == CommunicationStates.AttemptingToConnect
|| (this.IsConnected && serialPort != null && serialPort.IsOpen && !Disconnecting && readThreadHolder.IsCurrentThread()))
|| (this.IsConnected && SerialPort != null && SerialPort.IsOpen && !Disconnecting && readThreadHolder.IsCurrentThread()))
{
if ((this.IsConnected
|| this.CommunicationState == CommunicationStates.AttemptingToConnect)
@ -1522,13 +1522,13 @@ You will then need to logout and log back in to the computer for the changes to
try
{
while (serialPort != null
&& serialPort.BytesToRead > 0
while (SerialPort != null
&& SerialPort.BytesToRead > 0
&& readThreadHolder.IsCurrentThread())
{
lock (locker)
{
string allDataRead = serialPort.ReadExisting();
string allDataRead = SerialPort.ReadExisting();
allDataRead = allDataRead.Replace("\r\n", "\n");
allDataRead = allDataRead.Replace('\r', '\n');
dataLastRead += allDataRead;
@ -1730,21 +1730,21 @@ You will then need to logout and log back in to the computer for the changes to
if (Printer.Settings.PrinterSelected)
{
// first make sure we are not printing if possible (cancel slicing)
if (serialPort != null) // we still have a serial port
if (SerialPort != null) // we still have a serial port
{
Stop(false);
ClearQueuedGCode();
CommunicationState = CommunicationStates.Disconnecting;
currentReadThreadIndex++;
ToggleHighLowHigh(serialPort);
if (serialPort != null)
ToggleHighLowHigh(SerialPort);
if (SerialPort != null)
{
serialPort.Close();
serialPort.Dispose();
SerialPort.Close();
SerialPort.Dispose();
}
serialPort = null;
SerialPort = null;
// make sure we clear out the stream processors
CreateStreamProcessors();
CommunicationState = CommunicationStates.Disconnected;
@ -2113,11 +2113,11 @@ You will then need to logout and log back in to the computer for the changes to
CommunicationState = CommunicationStates.Disconnecting;
currentReadThreadIndex++;
if (serialPort != null)
if (SerialPort != null)
{
serialPort.Close();
serialPort.Dispose();
serialPort = null;
SerialPort.Close();
SerialPort.Dispose();
SerialPort = null;
}
CommunicationState = CommunicationStates.Disconnected;
@ -2790,7 +2790,7 @@ You will then need to logout and log back in to the computer for the changes to
{
if (this.IsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
{
if (serialPort != null && serialPort.IsOpen)
if (SerialPort != null && SerialPort.IsOpen)
{
if (lineWithoutChecksum.StartsWith("G92"))
{
@ -2858,7 +2858,7 @@ You will then need to logout and log back in to the computer for the changes to
{
lock (locker)
{
serialPort.Write(lineToWrite);
SerialPort.Write(lineToWrite);
timeSinceLastWrite.Restart();
timeHaveBeenWaitingForOK.Restart();
}