improving image to path controls
This commit is contained in:
parent
7e22f26770
commit
69d202170c
6 changed files with 215 additions and 87 deletions
|
|
@ -33,6 +33,7 @@ using MatterHackers.Agg;
|
||||||
using MatterHackers.Agg.Image;
|
using MatterHackers.Agg.Image;
|
||||||
using MatterHackers.Agg.Image.ThresholdFunctions;
|
using MatterHackers.Agg.Image.ThresholdFunctions;
|
||||||
using MatterHackers.Agg.UI;
|
using MatterHackers.Agg.UI;
|
||||||
|
using MatterHackers.Agg.VertexSource;
|
||||||
using MatterHackers.VectorMath;
|
using MatterHackers.VectorMath;
|
||||||
|
|
||||||
namespace MatterHackers.MatterControl.DesignTools
|
namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
@ -42,9 +43,9 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
private ImageBuffer _histogramRawCache = new ImageBuffer(256, 100);
|
private ImageBuffer _histogramRawCache = new ImageBuffer(256, 100);
|
||||||
private ThemeConfig theme;
|
private ThemeConfig theme;
|
||||||
|
|
||||||
public double RangeStart { get; set; } = .1;
|
public double RangeStart { get; set; } = 0;
|
||||||
|
|
||||||
public double RangeEnd { get; set; } = 1;
|
public double RangeEnd { get; set; } = .9;
|
||||||
|
|
||||||
private Color GetRGBA(byte[] buffer, int offset)
|
private Color GetRGBA(byte[] buffer, int offset)
|
||||||
{
|
{
|
||||||
|
|
@ -52,6 +53,8 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler RangeChanged;
|
public event EventHandler RangeChanged;
|
||||||
|
|
||||||
|
public event EventHandler EditComplete;
|
||||||
|
|
||||||
public void RebuildAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage)
|
public void RebuildAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage)
|
||||||
{
|
{
|
||||||
|
|
@ -97,7 +100,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
byte[] sourceBuffer = sourceImage.GetBuffer();
|
byte[] sourceBuffer = sourceImage.GetBuffer();
|
||||||
byte[] destBuffer = alphaImage.GetBuffer();
|
byte[] destBuffer = alphaImage.GetBuffer();
|
||||||
for (int y = 0; y < sourceImage.Height; y++)
|
Parallel.For(0, sourceImage.Height, (y) =>
|
||||||
{
|
{
|
||||||
int imageOffset = sourceImage.GetBufferOffsetY(y);
|
int imageOffset = sourceImage.GetBufferOffsetY(y);
|
||||||
|
|
||||||
|
|
@ -112,7 +115,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
destBuffer[imageBufferOffsetWithX + 2] = b;
|
destBuffer[imageBufferOffsetWithX + 2] = b;
|
||||||
destBuffer[imageBufferOffsetWithX + 3] = GetAlphaFromIntensity(r, g, b);
|
destBuffer[imageBufferOffsetWithX + 3] = GetAlphaFromIntensity(r, g, b);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
alphaImage.MarkImageChanged();
|
alphaImage.MarkImageChanged();
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +125,8 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
// build the histogram cache
|
// build the histogram cache
|
||||||
_histogramRawCache = new ImageBuffer(256, 100);
|
_histogramRawCache = new ImageBuffer(256, 100);
|
||||||
var counts = new int[_histogramRawCache.Width];
|
var counts = new int[_histogramRawCache.Width];
|
||||||
var function = new MapOnMaxIntensity(RangeStart, RangeEnd);
|
IThresholdFunction function = new MapOnMaxIntensity(RangeStart, RangeEnd);
|
||||||
|
function = new HueThresholdFunction(RangeStart, RangeEnd);
|
||||||
|
|
||||||
byte[] buffer = image.GetBuffer();
|
byte[] buffer = image.GetBuffer();
|
||||||
for (int y = 0; y < image.Height; y++)
|
for (int y = 0; y < image.Height; y++)
|
||||||
|
|
@ -141,7 +145,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
.OrderByDescending(vi => vi.value)
|
.OrderByDescending(vi => vi.value)
|
||||||
.First().value;
|
.First().value;
|
||||||
var graphics2D2 = _histogramRawCache.NewGraphics2D();
|
var graphics2D2 = _histogramRawCache.NewGraphics2D();
|
||||||
graphics2D2.Clear(Color.White);
|
graphics2D2.Clear(ApplicationController.Instance.Theme.SlightShade);
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
graphics2D2.Line(i, 0, i, Easing.Exponential.Out(counts[i] / max) * _histogramRawCache.Height, Color.Black);
|
graphics2D2.Line(i, 0, i, Easing.Exponential.Out(counts[i] / max) * _histogramRawCache.Height, Color.Black);
|
||||||
|
|
@ -156,7 +160,6 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
HAnchor = HAnchor.Stretch,
|
HAnchor = HAnchor.Stretch,
|
||||||
Height = 60 * GuiWidget.DeviceScale,
|
Height = 60 * GuiWidget.DeviceScale,
|
||||||
Margin = 5,
|
Margin = 5,
|
||||||
BackgroundColor = theme.SlightShade
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleWidth = 10 * GuiWidget.DeviceScale;
|
var handleWidth = 10 * GuiWidget.DeviceScale;
|
||||||
|
|
@ -167,15 +170,39 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
Margin = new BorderDouble(handleWidth, 0)
|
Margin = new BorderDouble(handleWidth, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
histogramBackground.AfterDraw += HistogramBackground_AfterDraw;
|
histogramBackground.AfterDraw += (s, e) =>
|
||||||
|
{
|
||||||
|
var rangeStart = RangeStart;
|
||||||
|
var rangeEnd = RangeEnd;
|
||||||
|
var graphics2D = e.Graphics2D;
|
||||||
|
graphics2D.Render(_histogramRawCache, 0, 0);
|
||||||
|
var background = _histogramRawCache;
|
||||||
|
graphics2D.FillRectangle(rangeStart * background.Width, 0, rangeEnd * background.Width, background.Height, theme.PrimaryAccentColor.WithAlpha(60));
|
||||||
|
};
|
||||||
|
|
||||||
histogramWidget.AddChild(histogramBackground);
|
histogramWidget.AddChild(histogramBackground);
|
||||||
|
|
||||||
|
void RenderHandle(Graphics2D g, double s, double e)
|
||||||
|
{
|
||||||
|
var w = g.Width;
|
||||||
|
var h = g.Height;
|
||||||
|
g.Line(w * e, 0, w * e, h, theme.TextColor);
|
||||||
|
var leftEdge = new VertexStorage();
|
||||||
|
leftEdge.MoveTo(w * e, h * .80);
|
||||||
|
leftEdge.curve3(w * e, h * .70, w * .5, h * .70);
|
||||||
|
leftEdge.curve3(w * s, h * .60);
|
||||||
|
leftEdge.LineTo(w * s, h * .40);
|
||||||
|
leftEdge.curve3(w * s, h * .30, w * .5, h * .30);
|
||||||
|
leftEdge.curve3(w * e, h * .20);
|
||||||
|
g.Render(new FlattenCurves(leftEdge), theme.TextColor);
|
||||||
|
g.Line(w * .35, h * .6, w * .35, h * .4, theme.BackgroundColor);
|
||||||
|
g.Line(w * .65, h * .6, w * .65, h * .4, theme.BackgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
var leftHandle = new ImageWidget((int)(handleWidth), (int)histogramWidget.Height);
|
var leftHandle = new ImageWidget((int)(handleWidth), (int)histogramWidget.Height);
|
||||||
leftHandle.Position = new Vector2(RangeStart * _histogramRawCache.Width, 0);
|
leftHandle.Position = new Vector2(RangeStart * _histogramRawCache.Width, 0);
|
||||||
var image = leftHandle.Image;
|
var image = leftHandle.Image;
|
||||||
var leftGraphics = image.NewGraphics2D();
|
RenderHandle(image.NewGraphics2D(), 0, 1);
|
||||||
leftGraphics.Line(image.Width, 0, image.Width, image.Height, theme.TextColor);
|
|
||||||
leftGraphics.FillRectangle(0, image.Height / 4, image.Width, image.Height / 4 * 3, theme.TextColor);
|
|
||||||
histogramWidget.AddChild(leftHandle);
|
histogramWidget.AddChild(leftHandle);
|
||||||
|
|
||||||
bool leftDown = false;
|
bool leftDown = false;
|
||||||
|
|
@ -193,23 +220,29 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
if (leftDown)
|
if (leftDown)
|
||||||
{
|
{
|
||||||
var offset = e.Position.X - leftX;
|
var offset = e.Position.X - leftX;
|
||||||
RangeStart += offset / _histogramRawCache.Width;
|
var newStart = RangeStart + offset / _histogramRawCache.Width;
|
||||||
RangeStart = Math.Max(0, Math.Min(RangeStart, RangeEnd));
|
newStart = agg_basics.Clamp(newStart, 0, RangeEnd);
|
||||||
leftHandle.Position = new Vector2(RangeStart * _histogramRawCache.Width, 0);
|
if (RangeStart != newStart)
|
||||||
RangeChanged?.Invoke(this, null);
|
{
|
||||||
|
RangeStart = newStart;
|
||||||
|
leftHandle.Position = new Vector2(RangeStart * _histogramRawCache.Width, 0);
|
||||||
|
RangeChanged?.Invoke(this, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
leftHandle.MouseUp += (s, e) =>
|
leftHandle.MouseUp += (s, e) =>
|
||||||
{
|
{
|
||||||
leftDown = false;
|
if (leftDown)
|
||||||
|
{
|
||||||
|
leftDown = false;
|
||||||
|
EditComplete?.Invoke(this, null);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var rightHandle = new ImageWidget((int)(handleWidth), (int)histogramWidget.Height);
|
var rightHandle = new ImageWidget((int)(handleWidth), (int)histogramWidget.Height);
|
||||||
rightHandle.Position = new Vector2(RangeEnd * _histogramRawCache.Width + handleWidth, 0);
|
rightHandle.Position = new Vector2(RangeEnd * _histogramRawCache.Width + handleWidth, 0);
|
||||||
image = rightHandle.Image;
|
image = rightHandle.Image;
|
||||||
var rightGraphics = image.NewGraphics2D();
|
RenderHandle(image.NewGraphics2D(), 1, 0);
|
||||||
rightGraphics.Line(0, 0, 0, image.Height, theme.TextColor);
|
|
||||||
rightGraphics.FillRectangle(0, image.Height / 4, image.Width, image.Height / 4 * 3, theme.TextColor);
|
|
||||||
histogramWidget.AddChild(rightHandle);
|
histogramWidget.AddChild(rightHandle);
|
||||||
|
|
||||||
bool rightDown = false;
|
bool rightDown = false;
|
||||||
|
|
@ -227,28 +260,26 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
if (rightDown)
|
if (rightDown)
|
||||||
{
|
{
|
||||||
var offset = e.Position.X - rightX;
|
var offset = e.Position.X - rightX;
|
||||||
RangeEnd += offset / _histogramRawCache.Width;
|
var newEnd = RangeEnd + offset / _histogramRawCache.Width;
|
||||||
RangeEnd = Math.Min(1, Math.Max(RangeStart, RangeEnd));
|
newEnd = agg_basics.Clamp(newEnd, RangeStart, 1);
|
||||||
rightHandle.Position = new Vector2(RangeEnd * _histogramRawCache.Width + handleWidth, 0);
|
if (RangeEnd != newEnd)
|
||||||
RangeChanged?.Invoke(this, null);
|
{
|
||||||
|
RangeEnd = newEnd;
|
||||||
|
rightHandle.Position = new Vector2(RangeEnd * _histogramRawCache.Width + handleWidth, 0);
|
||||||
|
RangeChanged?.Invoke(this, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
rightHandle.MouseUp += (s, e) =>
|
rightHandle.MouseUp += (s, e) =>
|
||||||
{
|
{
|
||||||
rightDown = false;
|
if (rightDown)
|
||||||
|
{
|
||||||
|
rightDown = false;
|
||||||
|
EditComplete?.Invoke(this, null);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return histogramWidget;
|
return histogramWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HistogramBackground_AfterDraw(object sender, DrawEventArgs e)
|
|
||||||
{
|
|
||||||
var rangeStart = RangeStart;
|
|
||||||
var rangeEnd = RangeEnd;
|
|
||||||
var graphics2D = e.Graphics2D;
|
|
||||||
graphics2D.Render(_histogramRawCache, 0, 0);
|
|
||||||
var background = _histogramRawCache;
|
|
||||||
graphics2D.FillRectangle(rangeStart * background.Width, 0, rangeEnd * background.Width, background.Height, theme.PrimaryAccentColor.WithAlpha(60));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -51,14 +52,14 @@ using Polygons = System.Collections.Generic.List<System.Collections.Generic.List
|
||||||
namespace MatterHackers.MatterControl.DesignTools
|
namespace MatterHackers.MatterControl.DesignTools
|
||||||
{
|
{
|
||||||
[HideMeterialAndColor]
|
[HideMeterialAndColor]
|
||||||
public class ImageToPathObject3D_2 : Object3D, IImageProvider, IPathObject, ISelectedEditorDraw, IObject3DControlsProvider
|
public class ImageToPathObject3D_2 : Object3D, IImageProvider, IPathObject, ISelectedEditorDraw, IObject3DControlsProvider, IPropertyGridModifier
|
||||||
{
|
{
|
||||||
public ImageToPathObject3D_2()
|
public ImageToPathObject3D_2()
|
||||||
{
|
{
|
||||||
Name = "Image to Path".Localize();
|
Name = "Image to Path".Localize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ThresholdFunctions
|
public enum FeatureDetectors
|
||||||
{
|
{
|
||||||
Transparency,
|
Transparency,
|
||||||
Colors,
|
Colors,
|
||||||
|
|
@ -75,14 +76,31 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_image == null)
|
if (_image == null
|
||||||
|
&& SourceImage != null)
|
||||||
{
|
{
|
||||||
_image = new ImageBuffer(SourceImage);
|
_image = new ImageBuffer(SourceImage);
|
||||||
IntensityHistogram.RebuildAlphaImage(SourceImage, _image);
|
IntensityHistogram.BuildHistogramFromImage(SourceImage);
|
||||||
IntensityHistogram.RangeChanged += (s, e) =>
|
IntensityHistogram.RangeChanged += (s, e) =>
|
||||||
|
{
|
||||||
|
IntensityHistogram.RebuildAlphaImage(SourceImage, _image);
|
||||||
|
};
|
||||||
|
|
||||||
|
IntensityHistogram.EditComplete += (s, e) =>
|
||||||
{
|
{
|
||||||
this.Invalidate(InvalidateType.Properties);
|
this.Invalidate(InvalidateType.Properties);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
switch (FeatureDetector)
|
||||||
|
{
|
||||||
|
case FeatureDetectors.Intensity:
|
||||||
|
IntensityHistogram.RebuildAlphaImage(SourceImage, _image);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FeatureDetectors.Transparency:
|
||||||
|
_image.CopyFrom(SourceImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _image;
|
return _image;
|
||||||
|
|
@ -94,8 +112,38 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private FeatureDetectors _featureDetector = FeatureDetectors.Intensity;
|
||||||
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)]
|
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)]
|
||||||
public ThresholdFunctions FeatureDetector { get; set; } = ThresholdFunctions.Intensity;
|
public FeatureDetectors FeatureDetector
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _featureDetector;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_featureDetector != value)
|
||||||
|
{
|
||||||
|
_featureDetector = value;
|
||||||
|
switch (FeatureDetector)
|
||||||
|
{
|
||||||
|
case FeatureDetectors.Intensity:
|
||||||
|
IntensityHistogram.RebuildAlphaImage(SourceImage, Image);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FeatureDetectors.Transparency:
|
||||||
|
Image?.CopyFrom(SourceImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisplayName("")]
|
||||||
|
[ReadOnly(true)]
|
||||||
|
public string TransparencyMessage { get; set; } = "Your image is processed as is with no modifications. Transparent pixels are ignored, only opaque pixels are considered in feature detection.";
|
||||||
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
private ImageBuffer SourceImage => ((IImageProvider)this.Descendants().Where(i => i is IImageProvider).FirstOrDefault())?.Image;
|
private ImageBuffer SourceImage => ((IImageProvider)this.Descendants().Where(i => i is IImageProvider).FirstOrDefault())?.Image;
|
||||||
|
|
@ -189,6 +237,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
&& !RebuildLocked)
|
&& !RebuildLocked)
|
||||||
{
|
{
|
||||||
IntensityHistogram.BuildHistogramFromImage(SourceImage);
|
IntensityHistogram.BuildHistogramFromImage(SourceImage);
|
||||||
|
IntensityHistogram.RebuildAlphaImage(SourceImage, _image);
|
||||||
await Rebuild();
|
await Rebuild();
|
||||||
}
|
}
|
||||||
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
|
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
|
||||||
|
|
@ -217,7 +266,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
var progressStatus = new ProgressStatus();
|
var progressStatus = new ProgressStatus();
|
||||||
switch (FeatureDetector)
|
switch (FeatureDetector)
|
||||||
{
|
{
|
||||||
case ThresholdFunctions.Transparency:
|
case FeatureDetectors.Transparency:
|
||||||
this.GenerateMarchingSquaresAndLines(
|
this.GenerateMarchingSquaresAndLines(
|
||||||
(progress0to1, status) =>
|
(progress0to1, status) =>
|
||||||
{
|
{
|
||||||
|
|
@ -229,7 +278,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
new AlphaFunction());
|
new AlphaFunction());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThresholdFunctions.Intensity:
|
case FeatureDetectors.Intensity:
|
||||||
this.GenerateMarchingSquaresAndLines(
|
this.GenerateMarchingSquaresAndLines(
|
||||||
(progress0to1, status) =>
|
(progress0to1, status) =>
|
||||||
{
|
{
|
||||||
|
|
@ -251,5 +300,11 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateControls(PublicPropertyChange change)
|
||||||
|
{
|
||||||
|
change.SetRowVisible(nameof(IntensityHistogram), () => FeatureDetector == FeatureDetectors.Intensity);
|
||||||
|
change.SetRowVisible(nameof(TransparencyMessage), () => FeatureDetector == FeatureDetectors.Transparency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,8 +36,10 @@ using MatterHackers.Agg;
|
||||||
using MatterHackers.Agg.Image;
|
using MatterHackers.Agg.Image;
|
||||||
using MatterHackers.Agg.ImageProcessing;
|
using MatterHackers.Agg.ImageProcessing;
|
||||||
using MatterHackers.Agg.Platform;
|
using MatterHackers.Agg.Platform;
|
||||||
|
using MatterHackers.Agg.UI;
|
||||||
using MatterHackers.DataConverters3D;
|
using MatterHackers.DataConverters3D;
|
||||||
using MatterHackers.Localizations;
|
using MatterHackers.Localizations;
|
||||||
|
using MatterHackers.MatterControl.DataStorage;
|
||||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||||
using MatterHackers.PolygonMesh;
|
using MatterHackers.PolygonMesh;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
@ -240,5 +242,45 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddEditorExtra(GuiWidget imageWidget, ThemeConfig theme, Action updateEditorImage)
|
||||||
|
{
|
||||||
|
imageWidget.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
if (e.Button == MouseButtons.Right)
|
||||||
|
{
|
||||||
|
var popupMenu = new PopupMenu(theme);
|
||||||
|
|
||||||
|
var pasteMenu = popupMenu.CreateMenuItem("Paste".Localize());
|
||||||
|
pasteMenu.Click += (s2, e2) =>
|
||||||
|
{
|
||||||
|
var activeImage = Clipboard.Instance.GetImage();
|
||||||
|
|
||||||
|
// Persist
|
||||||
|
string filePath = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".png");
|
||||||
|
ImageIO.SaveImageData(
|
||||||
|
filePath,
|
||||||
|
activeImage);
|
||||||
|
|
||||||
|
this.AssetPath = filePath;
|
||||||
|
this.Mesh = null;
|
||||||
|
|
||||||
|
updateEditorImage();
|
||||||
|
|
||||||
|
this.Invalidate(InvalidateType.Image);
|
||||||
|
};
|
||||||
|
|
||||||
|
pasteMenu.Enabled = Clipboard.Instance.ContainsImage;
|
||||||
|
|
||||||
|
var copyMenu = popupMenu.CreateMenuItem("Copy".Localize());
|
||||||
|
copyMenu.Click += (s2, e2) =>
|
||||||
|
{
|
||||||
|
Clipboard.Instance.SetImage(this.Image);
|
||||||
|
};
|
||||||
|
|
||||||
|
popupMenu.ShowMenu(imageWidget, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -618,6 +618,24 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
imageWidget.Margin = new BorderDouble(0, 3);
|
imageWidget.Margin = new BorderDouble(0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageWidget.BeforeDraw += (s, e) =>
|
||||||
|
{
|
||||||
|
// render a checkerboard that can show through the alpha mask
|
||||||
|
var g = e.Graphics2D;
|
||||||
|
var w = (int)(10 * GuiWidget.DeviceScale);
|
||||||
|
for (int x = 0; x < g.Width / w; x ++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < g.Height / w; y ++)
|
||||||
|
{
|
||||||
|
if (y % 2 == 0 && x % 2 == 1
|
||||||
|
|| y % 2 == 1 && x % 2 == 0)
|
||||||
|
{
|
||||||
|
g.FillRectangle(x * w, y * w, x * w + w, y * w + w, Color.LightGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ImageBuffer GetImageCheckingForErrors()
|
ImageBuffer GetImageCheckingForErrors()
|
||||||
{
|
{
|
||||||
var image = imageBuffer;
|
var image = imageBuffer;
|
||||||
|
|
@ -665,42 +683,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
if (object3D is ImageObject3D imageObject)
|
if (object3D is ImageObject3D imageObject)
|
||||||
{
|
{
|
||||||
imageWidget.Click += (s, e) =>
|
imageObject.AddEditorExtra(imageWidget, theme, UpdateEditorImage);
|
||||||
{
|
|
||||||
if (e.Button == MouseButtons.Right)
|
|
||||||
{
|
|
||||||
var popupMenu = new PopupMenu(theme);
|
|
||||||
|
|
||||||
var pasteMenu = popupMenu.CreateMenuItem("Paste".Localize());
|
|
||||||
pasteMenu.Click += (s2, e2) =>
|
|
||||||
{
|
|
||||||
var activeImage = Clipboard.Instance.GetImage();
|
|
||||||
|
|
||||||
// Persist
|
|
||||||
string filePath = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".png");
|
|
||||||
ImageIO.SaveImageData(
|
|
||||||
filePath,
|
|
||||||
activeImage);
|
|
||||||
|
|
||||||
imageObject.AssetPath = filePath;
|
|
||||||
imageObject.Mesh = null;
|
|
||||||
|
|
||||||
UpdateEditorImage();
|
|
||||||
|
|
||||||
imageObject.Invalidate(InvalidateType.Image);
|
|
||||||
};
|
|
||||||
|
|
||||||
pasteMenu.Enabled = Clipboard.Instance.ContainsImage;
|
|
||||||
|
|
||||||
var copyMenu = popupMenu.CreateMenuItem("Copy".Localize());
|
|
||||||
copyMenu.Click += (s2, e2) =>
|
|
||||||
{
|
|
||||||
Clipboard.Instance.SetImage(imageObject.Image);
|
|
||||||
};
|
|
||||||
|
|
||||||
popupMenu.ShowMenu(imageWidget, e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rowContainer.AddChild(imageWidget);
|
rowContainer.AddChild(imageWidget);
|
||||||
|
|
|
||||||
|
|
@ -249,29 +249,46 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
["index2"] = (owner) => RetrieveArrayIndex(owner, 2),
|
["index2"] = (owner) => RetrieveArrayIndex(owner, 2),
|
||||||
};
|
};
|
||||||
|
|
||||||
private static ArrayObject3D FindParentArray(IObject3D item, int level)
|
private static ArrayObject3D FindParentArray(IObject3D item, int wantLevel)
|
||||||
{
|
{
|
||||||
|
int foundLevel = 0;
|
||||||
// look through all the parents
|
// look through all the parents
|
||||||
foreach (var parent in item.Parents())
|
foreach (var parent in item.Parents())
|
||||||
{
|
{
|
||||||
// then each child of any give parent
|
// if it is a sheet
|
||||||
foreach (var sibling in parent.Children)
|
if (parent is ArrayObject3D arrayObject)
|
||||||
{
|
{
|
||||||
// if it is a sheet
|
if (foundLevel == wantLevel)
|
||||||
if (sibling != item
|
|
||||||
&& sibling is SheetObject3D sheet)
|
|
||||||
{
|
{
|
||||||
return sheet;
|
return arrayObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foundLevel++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double RetrieveArrayIndex(IObject3D owner, int level)
|
private static int RetrieveArrayIndex(IObject3D owner, int level)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var arrayObject = FindParentArray(owner, level);
|
||||||
|
|
||||||
|
if (arrayObject != null)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach(var child in arrayObject.Children)
|
||||||
|
{
|
||||||
|
if (child == owner)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ReplaceConstantsWithValues(IObject3D owner, string stringWithConstants)
|
private static string ReplaceConstantsWithValues(IObject3D owner, string stringWithConstants)
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3355908f5e59e8f0afa64478111071d656ab5d47
|
Subproject commit 2ec468c986a2e2a4b65fc092e120760d3f0e1a2d
|
||||||
Loading…
Add table
Add a link
Reference in a new issue