Migrate nozzle limits texture construction to drawable
- Construct and cache textures after use - Create placeholder textures for use before constructed - Remove bed texture construction from CreatePrintBedAndVolume - Issue MatterHackers/MCCentral#5325 Migrate to themed bed colors - Issue MatterHackers/MCCentral#5320 Cache per hotend bed textures
This commit is contained in:
parent
17eca3b36c
commit
60a1238f54
5 changed files with 180 additions and 139 deletions
|
|
@ -435,12 +435,6 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
private Mesh _bedMesh;
|
||||
|
||||
[JsonIgnore]
|
||||
public ImageBuffer ActiveBedImage { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ImageBuffer GeneratedBedImage { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Mesh Mesh
|
||||
{
|
||||
|
|
@ -449,9 +443,7 @@ namespace MatterHackers.MatterControl
|
|||
if (_bedMesh == null)
|
||||
{
|
||||
// Load bed and build volume meshes
|
||||
(_bedMesh, _buildVolumeMesh, this.ActiveBedImage) = BedMeshGenerator.CreatePrintBedAndVolume(Printer);
|
||||
|
||||
this.GeneratedBedImage = new ImageBuffer(this.ActiveBedImage);
|
||||
(_bedMesh, _buildVolumeMesh) = BedMeshGenerator.CreatePrintBedAndVolume(Printer);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,8 +28,15 @@ either expressed or implied, of the FreeBSD Project.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
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.SlicerConfiguration;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
|
@ -41,14 +48,23 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
private ISceneContext sceneContext;
|
||||
private InteractionLayer.EditorType editorType;
|
||||
private ThemeConfig theme;
|
||||
private PrinterConfig printer;
|
||||
|
||||
private Color buildVolumeColor;
|
||||
|
||||
private int activeBedHotendClippingImage = -1;
|
||||
|
||||
private ImageBuffer[] bedTextures = null;
|
||||
|
||||
private bool loadingTextures = false;
|
||||
|
||||
public FloorDrawable(InteractionLayer.EditorType editorType, ISceneContext sceneContext, Color buildVolumeColor, ThemeConfig theme)
|
||||
{
|
||||
this.buildVolumeColor = buildVolumeColor;
|
||||
this.sceneContext = sceneContext;
|
||||
this.editorType = editorType;
|
||||
this.theme = theme;
|
||||
this.printer = sceneContext.Printer;
|
||||
|
||||
{
|
||||
}
|
||||
|
|
@ -71,6 +87,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
// only render if we are above the bed
|
||||
if (sceneContext.RendererOptions.RenderBed)
|
||||
{
|
||||
this.UpdateFloorImage(sceneContext.Scene.SelectedItem);
|
||||
|
||||
GLHelper.Render(
|
||||
sceneContext.Mesh,
|
||||
theme.UnderBedColor,
|
||||
|
|
@ -142,6 +160,158 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
|
||||
private void UpdateFloorImage(IObject3D selectedItem)
|
||||
{
|
||||
// Early exit for invalid cases
|
||||
if (loadingTextures
|
||||
|| printer == null
|
||||
|| printer.Settings.Helpers.NumberOfHotends() != 2
|
||||
|| printer.Bed.BedShape != BedShape.Rectangular)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bedTextures != null)
|
||||
{
|
||||
int hotendIndex = GetActiveHotendIndex(selectedItem);
|
||||
|
||||
if (activeBedHotendClippingImage != hotendIndex)
|
||||
{
|
||||
this.SetActiveTexture(bedTextures[hotendIndex + 1]);
|
||||
activeBedHotendClippingImage = hotendIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loadingTextures = true;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var placeHolderImage = new ImageBuffer(5, 5);
|
||||
var graphics = placeHolderImage.NewGraphics2D();
|
||||
graphics.Clear(theme.BedColor);
|
||||
|
||||
SetActiveTexture(placeHolderImage);
|
||||
|
||||
try
|
||||
{
|
||||
var bedImage = BedMeshGenerator.CreatePrintBedImage(sceneContext.Printer);
|
||||
|
||||
bedTextures = new[]
|
||||
{
|
||||
bedImage, // No limits, basic themed bed
|
||||
new ImageBuffer(bedImage), // T0 limits
|
||||
new ImageBuffer(bedImage), // T1 limits
|
||||
new ImageBuffer(bedImage) // Unioned T0 & T1 limits
|
||||
};
|
||||
|
||||
GenerateNozzleLimitsTexture(printer, 0, bedTextures[1]);
|
||||
GenerateNozzleLimitsTexture(printer, 1, bedTextures[2]);
|
||||
|
||||
// TODO:
|
||||
// GenerateNozzleLimitsTexture(printer, 3, bedTextures[3]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
loadingTextures = false;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void SetActiveTexture(ImageBuffer bedTexture)
|
||||
{
|
||||
foreach (var texture in printer.Bed.Mesh.FaceTextures)
|
||||
{
|
||||
texture.Value.image = bedTexture;
|
||||
}
|
||||
|
||||
printer.Bed.Mesh.PropertyBag.Clear();
|
||||
}
|
||||
|
||||
private static int GetActiveHotendIndex(IObject3D selectedItem)
|
||||
{
|
||||
if (selectedItem == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var worldMaterialIndex = selectedItem.WorldMaterialIndex();
|
||||
if (worldMaterialIndex == -1)
|
||||
{
|
||||
worldMaterialIndex = 0;
|
||||
}
|
||||
|
||||
return worldMaterialIndex;
|
||||
}
|
||||
|
||||
private void GenerateNozzleLimitsTexture(PrinterConfig printer, int hotendIndex, ImageBuffer bedplateImage)
|
||||
{
|
||||
var xScale = bedplateImage.Width / printer.Settings.BedBounds.Width;
|
||||
var yScale = bedplateImage.Height / printer.Settings.BedBounds.Height;
|
||||
|
||||
int alpha = 80;
|
||||
|
||||
var graphics = bedplateImage.NewGraphics2D();
|
||||
|
||||
var hotendBounds = printer.Settings.HotendBounds[hotendIndex];
|
||||
|
||||
// Scale hotendBounds into textures units
|
||||
hotendBounds = new RectangleDouble(
|
||||
hotendBounds.Left * xScale,
|
||||
hotendBounds.Bottom * yScale,
|
||||
hotendBounds.Right * xScale,
|
||||
hotendBounds.Top * yScale);
|
||||
|
||||
var imageBounds = bedplateImage.GetBounds();
|
||||
|
||||
var dimRegion = new VertexStorage();
|
||||
dimRegion.MoveTo(imageBounds.Left, imageBounds.Bottom);
|
||||
dimRegion.LineTo(imageBounds.Right, imageBounds.Bottom);
|
||||
dimRegion.LineTo(imageBounds.Right, imageBounds.Top);
|
||||
dimRegion.LineTo(imageBounds.Left, imageBounds.Top);
|
||||
|
||||
var targetRect = new VertexStorage();
|
||||
targetRect.MoveTo(hotendBounds.Right, hotendBounds.Bottom);
|
||||
targetRect.LineTo(hotendBounds.Left, hotendBounds.Bottom);
|
||||
targetRect.LineTo(hotendBounds.Left, hotendBounds.Top);
|
||||
targetRect.LineTo(hotendBounds.Right, hotendBounds.Top);
|
||||
targetRect.ClosePolygon();
|
||||
|
||||
var overlayMinusTargetRect = new CombinePaths(dimRegion, targetRect);
|
||||
graphics.Render(overlayMinusTargetRect, new Color(Color.Black, alpha));
|
||||
|
||||
string hotendTitle = string.Format("{0} {1}", "Nozzle ".Localize(), hotendIndex + 1);
|
||||
|
||||
var stringPrinter = new TypeFacePrinter(hotendTitle, theme.DefaultFontSize, bold: true);
|
||||
var printerBounds = stringPrinter.GetBounds();
|
||||
|
||||
int textPadding = 8;
|
||||
|
||||
var textBounds = printerBounds;
|
||||
textBounds.Inflate(textPadding);
|
||||
|
||||
var cornerRect = new RectangleDouble(hotendBounds.Right - textBounds.Width, hotendBounds.Top - textBounds.Height, hotendBounds.Right, hotendBounds.Top);
|
||||
|
||||
graphics.Render(
|
||||
new RoundedRectShape(cornerRect, bottomLeftRadius: 6),
|
||||
theme.PrimaryAccentColor);
|
||||
|
||||
graphics.DrawString(
|
||||
hotendTitle,
|
||||
hotendBounds.Right - textPadding,
|
||||
cornerRect.Bottom + (cornerRect.Height / 2 - printerBounds.Height / 2) + 1,
|
||||
theme.DefaultFontSize,
|
||||
justification: Justification.Right,
|
||||
baseline: Baseline.Text,
|
||||
color: Color.White,
|
||||
bold: true);
|
||||
|
||||
graphics.Render(new Stroke(targetRect, 1), theme.PrimaryAccentColor);
|
||||
}
|
||||
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,14 +68,17 @@ namespace MatterHackers.MatterControl
|
|||
return bedImage;
|
||||
}
|
||||
|
||||
public static (Mesh bed, Mesh volume, ImageBuffer bedImage) CreatePrintBedAndVolume(PrinterConfig printer)
|
||||
public static (Mesh bed, Mesh volume) CreatePrintBedAndVolume(PrinterConfig printer)
|
||||
{
|
||||
Mesh printerBed = null;
|
||||
Mesh buildVolume = null;
|
||||
|
||||
Vector3 displayVolumeToBuild = Vector3.ComponentMax(printer.Bed.ViewerVolume, new Vector3(1, 1, 1));
|
||||
|
||||
ImageBuffer bedplateImage = CreatePrintBedImage(printer);
|
||||
// Temporarily assign a placeholder image as the mesh texture. This will be replaced with a themed image by the view
|
||||
var placeHolderImage = new ImageBuffer(5, 5);
|
||||
var graphics = placeHolderImage.NewGraphics2D();
|
||||
graphics.Clear(Color.Gray.WithAlpha(40));
|
||||
|
||||
switch (printer.Bed.BedShape)
|
||||
{
|
||||
|
|
@ -87,12 +90,13 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
buildVolume.Vertices[i] = buildVolume.Vertices[i] + new Vector3Float(0, 0, displayVolumeToBuild.Z / 2);
|
||||
}
|
||||
|
||||
var bspTree = FaceBspTree.Create(buildVolume);
|
||||
buildVolume.FaceBspTree = bspTree;
|
||||
}
|
||||
|
||||
printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.X, displayVolumeToBuild.Y, 1.8);
|
||||
printerBed.PlaceTextureOnFaces(0, bedplateImage);
|
||||
printerBed.PlaceTextureOnFaces(0, placeHolderImage);
|
||||
break;
|
||||
|
||||
case BedShape.Circular:
|
||||
|
|
@ -103,7 +107,7 @@ namespace MatterHackers.MatterControl
|
|||
}
|
||||
|
||||
printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), 1.8);
|
||||
printerBed.PlaceTextureOnFaces(0, bedplateImage);
|
||||
printerBed.PlaceTextureOnFaces(0, placeHolderImage);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -125,7 +129,7 @@ namespace MatterHackers.MatterControl
|
|||
}
|
||||
}
|
||||
|
||||
return (printerBed, buildVolume, bedplateImage);
|
||||
return (printerBed, buildVolume);
|
||||
}
|
||||
|
||||
private static ImageBuffer CreateCircularBedGridImage(PrinterConfig printer)
|
||||
|
|
|
|||
|
|
@ -134,8 +134,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|| settingsKey == SettingsKey.bed_size
|
||||
|| settingsKey == SettingsKey.print_center)
|
||||
{
|
||||
activeBedHotendClippingImage = -1;
|
||||
this.UpdateFloorImage(sceneContext.Scene.SelectedItem);
|
||||
this.Invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,8 +490,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
|
||||
}
|
||||
|
||||
this.UpdateFloorImage(selectedItem);
|
||||
|
||||
DrawInteractionVolumes(e);
|
||||
|
||||
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.TransparentContent))
|
||||
|
|
@ -528,127 +526,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
|
||||
int activeBedHotendClippingImage = -1;
|
||||
|
||||
private void UpdateFloorImage(IObject3D selectedItem)
|
||||
{
|
||||
if (sceneContext.Printer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bed = sceneContext as BedConfig;
|
||||
var printer = sceneContext.Printer;
|
||||
|
||||
int hotendIndex;
|
||||
|
||||
if (selectedItem == null)
|
||||
{
|
||||
hotendIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var worldMaterialIndex = selectedItem.WorldMaterialIndex();
|
||||
if (worldMaterialIndex == -1)
|
||||
{
|
||||
worldMaterialIndex = 0;
|
||||
}
|
||||
|
||||
hotendIndex = worldMaterialIndex;
|
||||
}
|
||||
|
||||
if (activeBedHotendClippingImage != hotendIndex)
|
||||
{
|
||||
ImageBuffer bedplateImage;
|
||||
if (hotendIndex == -1)
|
||||
{
|
||||
// Reset back to default
|
||||
bedplateImage = bed.GeneratedBedImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new image from current bed texture image
|
||||
bedplateImage = new ImageBuffer(bed.GeneratedBedImage);
|
||||
|
||||
if (printer.Settings.Helpers.NumberOfHotends() == 2
|
||||
&& printer.Bed.BedShape == BedShape.Rectangular
|
||||
&& (hotendIndex == 0 || hotendIndex == 1))
|
||||
{
|
||||
var xScale = bedplateImage.Width / printer.Settings.BedBounds.Width;
|
||||
var yScale = bedplateImage.Height / printer.Settings.BedBounds.Height;
|
||||
|
||||
int alpha = 80;
|
||||
|
||||
var graphics = bedplateImage.NewGraphics2D();
|
||||
|
||||
var hotendBounds = printer.Settings.HotendBounds[hotendIndex];
|
||||
|
||||
// Scale hotendBounds into textures units
|
||||
hotendBounds = new RectangleDouble(
|
||||
hotendBounds.Left * xScale,
|
||||
hotendBounds.Bottom * yScale,
|
||||
hotendBounds.Right * xScale,
|
||||
hotendBounds.Top * yScale);
|
||||
|
||||
var imageBounds = bedplateImage.GetBounds();
|
||||
|
||||
var dimRegion = new VertexStorage();
|
||||
dimRegion.MoveTo(imageBounds.Left, imageBounds.Bottom);
|
||||
dimRegion.LineTo(imageBounds.Right, imageBounds.Bottom);
|
||||
dimRegion.LineTo(imageBounds.Right, imageBounds.Top);
|
||||
dimRegion.LineTo(imageBounds.Left, imageBounds.Top);
|
||||
|
||||
var targetRect = new VertexStorage();
|
||||
targetRect.MoveTo(hotendBounds.Right, hotendBounds.Bottom);
|
||||
targetRect.LineTo(hotendBounds.Left, hotendBounds.Bottom);
|
||||
targetRect.LineTo(hotendBounds.Left, hotendBounds.Top);
|
||||
targetRect.LineTo(hotendBounds.Right, hotendBounds.Top);
|
||||
targetRect.ClosePolygon();
|
||||
|
||||
var overlayMinusTargetRect = new CombinePaths(dimRegion, targetRect);
|
||||
graphics.Render(overlayMinusTargetRect, new Color(Color.Black, alpha));
|
||||
|
||||
string hotendTitle = string.Format("{0} {1}", "Nozzle ".Localize(), hotendIndex + 1);
|
||||
|
||||
var stringPrinter = new TypeFacePrinter(hotendTitle, theme.DefaultFontSize, bold: true);
|
||||
var printerBounds = stringPrinter.GetBounds();
|
||||
|
||||
int textPadding = 8;
|
||||
|
||||
var textBounds = printerBounds;
|
||||
textBounds.Inflate(textPadding);
|
||||
|
||||
var cornerRect = new RectangleDouble(hotendBounds.Right - textBounds.Width, hotendBounds.Top - textBounds.Height, hotendBounds.Right, hotendBounds.Top);
|
||||
|
||||
graphics.Render(
|
||||
new RoundedRectShape(cornerRect, bottomLeftRadius: 6),
|
||||
theme.PrimaryAccentColor);
|
||||
|
||||
graphics.DrawString(
|
||||
hotendTitle,
|
||||
hotendBounds.Right - textPadding,
|
||||
cornerRect.Bottom + (cornerRect.Height / 2 - printerBounds.Height / 2) + 1,
|
||||
theme.DefaultFontSize,
|
||||
justification: Justification.Right,
|
||||
baseline: Baseline.Text,
|
||||
color: Color.White,
|
||||
bold: true);
|
||||
|
||||
graphics.Render(new Stroke(targetRect, 1), theme.PrimaryAccentColor);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var texture in bed.Mesh.FaceTextures)
|
||||
{
|
||||
texture.Value.image = bedplateImage;
|
||||
}
|
||||
|
||||
bed.Mesh.PropertyBag.Clear();
|
||||
|
||||
activeBedHotendClippingImage = hotendIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawInteractionVolumes(DrawEventArgs e)
|
||||
{
|
||||
if(SuppressUiVolumes)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue