mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-08 17:42:31 +02:00
Merge pull request #635 from sn4k3/anet-n7
Add support for Anet N7 and future Anet printers in same format
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# generated by PrusaSlicer 2.5.0+win64 on 2023-01-01 at 18:22:58 UTC
|
||||
absolute_correction = 0
|
||||
area_fill = 50
|
||||
bed_custom_model =
|
||||
bed_custom_texture =
|
||||
bed_shape = 0x0,192x0,192x120,0x120
|
||||
default_sla_material_profile = Prusa Orange Tough 0.05
|
||||
default_sla_print_profile = 0.05 Normal
|
||||
display_height = 120
|
||||
display_mirror_x = 1
|
||||
display_mirror_y = 0
|
||||
display_orientation = landscape
|
||||
display_pixels_x = 2560
|
||||
display_pixels_y = 1600
|
||||
display_width = 192
|
||||
elefant_foot_compensation = 0.2
|
||||
elefant_foot_min_width = 0.2
|
||||
fast_tilt_time = 5
|
||||
gamma_correction = 0
|
||||
high_viscosity_tilt_time = 10
|
||||
host_type = octoprint
|
||||
inherits = Original Prusa SL1
|
||||
max_exposure_time = 120
|
||||
max_initial_exposure_time = 300
|
||||
max_print_height = 300
|
||||
min_exposure_time = 1
|
||||
min_initial_exposure_time = 1
|
||||
print_host =
|
||||
printer_model = SL1
|
||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_SL1\nPRINTER_VENDOR_ANET\nPRINTER_MODEL_N7\nFILEFORMAT_N7\n\nSTART_CUSTOM_VALUES\nLiftHeight_6\nLiftSpeed_60\nEND_CUSTOM_VALUES
|
||||
printer_settings_id =
|
||||
printer_technology = SLA
|
||||
printer_variant = default
|
||||
printer_vendor =
|
||||
printhost_apikey =
|
||||
printhost_cafile =
|
||||
relative_correction = 1,1
|
||||
relative_correction_x = 1
|
||||
relative_correction_y = 1
|
||||
relative_correction_z = 1
|
||||
slow_tilt_time = 8
|
||||
thumbnails = 260x140
|
||||
@@ -139,6 +139,7 @@ But also, I need victims for test subject. Proceed at your own risk!
|
||||
- LGS4K (Longer Orange 4K & mono)
|
||||
- Flashforge SVGX
|
||||
- Anet N4
|
||||
- Anet N7
|
||||
- ZIP (Generic / Phrozen Zip)
|
||||
- VDA.ZIP (Voxeldance Additive)
|
||||
- VDT (Voxeldance Tango)
|
||||
|
||||
@@ -73,7 +73,7 @@ public static class SizeExtensions
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <returns></returns>
|
||||
public static bool HaveZero(this Size size) => size.Width <= 0 && size.Height <= 0;
|
||||
public static bool HaveZero(this Size size) => size.Width <= 0 || size.Height <= 0;
|
||||
|
||||
/// <summary>
|
||||
/// Exchange width with height
|
||||
@@ -96,7 +96,7 @@ public static class SizeExtensions
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <returns></returns>
|
||||
public static bool HaveZero(this SizeF size) => size.Width <= 0 && size.Height <= 0;
|
||||
public static bool HaveZero(this SizeF size) => size.Width <= 0 || size.Height <= 0;
|
||||
|
||||
public static float Area(this SizeF size, int round = -1) => round >= 0 ? (float)Math.Round(size.Width * size.Height, round) : size.Width * size.Height;
|
||||
|
||||
|
||||
@@ -13,11 +13,13 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UVtools.Core.Converters;
|
||||
using UVtools.Core.Extensions;
|
||||
using UVtools.Core.Layers;
|
||||
using UVtools.Core.Operations;
|
||||
using UVtools.Core.Printer;
|
||||
|
||||
namespace UVtools.Core.FileFormats;
|
||||
|
||||
@@ -26,16 +28,23 @@ namespace UVtools.Core.FileFormats;
|
||||
/// and added several new fields (as example, preview image).
|
||||
/// Some of the format features are not recommended to use (BaseLayersCount and FilledBaseLayersCount).
|
||||
/// </summary>
|
||||
public sealed class AnetN4File : FileFormat
|
||||
public sealed class AnetFile : FileFormat
|
||||
{
|
||||
#region Constants
|
||||
|
||||
public const ushort RESOLUTION_X = 1440;
|
||||
public const ushort RESOLUTION_Y = 2560;
|
||||
public const ushort RESOLUTION_N4_X = 1440;
|
||||
public const ushort RESOLUTION_N4_Y = 2560;
|
||||
|
||||
public const float DISPLAY_WIDTH = 68.04f;
|
||||
public const float DISPLAY_HEIGHT = 120.96f;
|
||||
public const float MACHINE_Z = 135f;
|
||||
public const float DISPLAY_N4_WIDTH = 68.04f;
|
||||
public const float DISPLAY_N4_HEIGHT = 120.96f;
|
||||
public const float MACHINE_N4_Z = 135f;
|
||||
|
||||
public const ushort RESOLUTION_N7_X = 2560;
|
||||
public const ushort RESOLUTION_N7_Y = 1600;
|
||||
|
||||
public const float DISPLAY_N7_WIDTH = 192f;
|
||||
public const float DISPLAY_N7_HEIGHT = 120f;
|
||||
public const float MACHINE_N7_Z = 300f;
|
||||
|
||||
/// <summary>
|
||||
/// Printer uses incorrect BMP header for preview image so we need to use it as-is instead of generating.
|
||||
@@ -44,13 +53,13 @@ public sealed class AnetN4File : FileFormat
|
||||
|
||||
#endregion
|
||||
|
||||
#region Members
|
||||
#region Enums
|
||||
|
||||
private uint _resolutionX = RESOLUTION_X;
|
||||
private uint _resolutionY = RESOLUTION_Y;
|
||||
|
||||
private float _displayWidth = DISPLAY_WIDTH;
|
||||
private float _displayHeight = DISPLAY_HEIGHT;
|
||||
public enum AnetPrinter : byte
|
||||
{
|
||||
N4,
|
||||
N7
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -58,7 +67,7 @@ public sealed class AnetN4File : FileFormat
|
||||
|
||||
#region Header
|
||||
|
||||
public class Header
|
||||
public class AnetHeader
|
||||
{
|
||||
[FieldOrder(0)][FieldEndianness(Endianness.Big)] public int VersionLength { get; set; } = 2;
|
||||
[FieldOrder(1)][FieldEncoding("UTF-16BE")][FieldLength(nameof(VersionLength))] public string Version { get; set; } = "3";
|
||||
@@ -155,10 +164,11 @@ public sealed class AnetN4File : FileFormat
|
||||
}
|
||||
}
|
||||
|
||||
if (mat.Width != RESOLUTION_X || mat.Height != RESOLUTION_Y)
|
||||
// Format does not have a global resolution field but supports multiple resolutions
|
||||
/*if (mat.Width != RESOLUTION_X || mat.Height != RESOLUTION_Y)
|
||||
{
|
||||
throw new ArgumentException($"Anet N4 support only {RESOLUTION_X}x{RESOLUTION_Y} image, got {mat.Width}x{mat.Height}");
|
||||
}
|
||||
}*/
|
||||
|
||||
WhitePixelsCount = 0;
|
||||
uint singleColorLength = 0;
|
||||
@@ -205,7 +215,7 @@ public sealed class AnetN4File : FileFormat
|
||||
return EncodedRle;
|
||||
}
|
||||
|
||||
public Mat Decode(bool consumeRle = true)
|
||||
public Mat Decode(out uint resolutionX, out uint resolutionY, bool consumeRle = true)
|
||||
{
|
||||
uint GetBits(uint pos, uint count = 1)
|
||||
{
|
||||
@@ -231,10 +241,10 @@ public sealed class AnetN4File : FileFormat
|
||||
throw new IndexOutOfRangeException($"Incorrect RLE data size {EncodedRle.Length * 8}, except {BitsCount} bits.");
|
||||
}
|
||||
|
||||
uint rleWidth = GetBits(0, 16);
|
||||
uint rleHeight = GetBits(16, 16);
|
||||
resolutionX = GetBits(0, 16);
|
||||
resolutionY = GetBits(16, 16);
|
||||
|
||||
var mat = EmguExtensions.InitMat(new Size((int)rleWidth, (int)rleHeight));
|
||||
var mat = EmguExtensions.InitMat(new Size((int)resolutionX, (int)resolutionY));
|
||||
var imageLength = mat.GetLength();
|
||||
|
||||
byte brightness = (byte)((GetBits(32) == 1) ? 0xff : 0x0);
|
||||
@@ -261,11 +271,15 @@ public sealed class AnetN4File : FileFormat
|
||||
|
||||
#region Properties
|
||||
|
||||
public Header HeaderSettings { get; private set; } = new();
|
||||
public AnetHeader HeaderSettings { get; private set; } = new();
|
||||
|
||||
public override FileFormatType FileType => FileFormatType.Binary;
|
||||
|
||||
public override string ConvertMenuGroup => "Anet";
|
||||
|
||||
public override FileExtension[] FileExtensions { get; } = {
|
||||
new(typeof(AnetN4File), "n4", "Anet N4"),
|
||||
new(typeof(AnetFile), "n4", "Anet N4"),
|
||||
new(typeof(AnetFile), "n7", "Anet N7"),
|
||||
};
|
||||
|
||||
public override SpeedUnit FormatSpeedUnit => SpeedUnit.MillimetersPerSecond;
|
||||
@@ -283,48 +297,6 @@ public sealed class AnetN4File : FileFormat
|
||||
|
||||
public override Size[]? ThumbnailsOriginalSize { get; } = { new(260, 140) };
|
||||
|
||||
public override uint ResolutionX
|
||||
{
|
||||
get => _resolutionX;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _resolutionX, value)) return;
|
||||
if(value != RESOLUTION_X) throw new ArgumentException($"Anet N4 support only {RESOLUTION_X}x{RESOLUTION_Y} image, got {ResolutionX}x{ResolutionY}");
|
||||
HeaderSettings.XYPixelSize = PixelSizeMax;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint ResolutionY
|
||||
{
|
||||
get => _resolutionY;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _resolutionY, value)) return;
|
||||
if (value != RESOLUTION_Y) throw new ArgumentException($"Anet N4 support only {RESOLUTION_X}x{RESOLUTION_Y} image, got {ResolutionX}x{ResolutionY}");
|
||||
HeaderSettings.XYPixelSize = PixelSizeMax;
|
||||
}
|
||||
}
|
||||
|
||||
public override float DisplayWidth
|
||||
{
|
||||
get => _displayWidth;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _displayWidth, value)) return;
|
||||
HeaderSettings.XYPixelSize = PixelSizeMax;
|
||||
}
|
||||
}
|
||||
|
||||
public override float DisplayHeight
|
||||
{
|
||||
get => _displayHeight;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _displayHeight, value)) return;
|
||||
HeaderSettings.XYPixelSize = PixelSizeMax;
|
||||
}
|
||||
}
|
||||
|
||||
public override FlipDirection DisplayMirror
|
||||
{
|
||||
get => FlipDirection.Horizontally;
|
||||
@@ -409,21 +381,53 @@ public sealed class AnetN4File : FileFormat
|
||||
}
|
||||
}
|
||||
|
||||
public override string MachineName => "Anet N4";
|
||||
|
||||
public override object[] Configs => new object[] { HeaderSettings };
|
||||
|
||||
public AnetPrinter PrinterModel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FileEndsWith(".n4"))
|
||||
{
|
||||
return AnetPrinter.N4;
|
||||
}
|
||||
|
||||
if (FileEndsWith(".n7"))
|
||||
{
|
||||
return AnetPrinter.N7;
|
||||
}
|
||||
|
||||
return AnetPrinter.N4;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public AnetN4File()
|
||||
{
|
||||
MachineZ = MACHINE_Z;
|
||||
}
|
||||
|
||||
public AnetFile() { }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void OnBeforeEncode(bool isPartialEncode)
|
||||
{
|
||||
switch (PrinterModel)
|
||||
{
|
||||
case AnetPrinter.N4:
|
||||
if (ResolutionX != RESOLUTION_N4_X || ResolutionY != RESOLUTION_N4_Y)
|
||||
throw new ArgumentException($"Anet N4 support only {RESOLUTION_N4_X}x{RESOLUTION_N4_Y} image, got {ResolutionX}x{ResolutionY}");
|
||||
break;
|
||||
case AnetPrinter.N7:
|
||||
if (ResolutionX != RESOLUTION_N7_X || ResolutionY != RESOLUTION_N7_Y)
|
||||
throw new ArgumentException($"Anet N7 support only {RESOLUTION_N7_X}x{RESOLUTION_N7_Y} image, got {ResolutionX}x{ResolutionY}");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(PrinterModel), FileExtension);
|
||||
}
|
||||
HeaderSettings.XYPixelSize = PixelSizeMax;
|
||||
}
|
||||
|
||||
protected override void EncodeInternally(OperationProgress progress)
|
||||
{
|
||||
using var outputFile = new FileStream(TemporaryOutputFileFullPath, FileMode.Create, FileAccess.Write);
|
||||
@@ -479,7 +483,7 @@ public sealed class AnetN4File : FileFormat
|
||||
protected override void DecodeInternally(OperationProgress progress)
|
||||
{
|
||||
using var inputFile = new FileStream(FileFullPath!, FileMode.Open, FileAccess.Read);
|
||||
HeaderSettings = Helpers.Deserialize<Header>(inputFile);
|
||||
HeaderSettings = Helpers.Deserialize<AnetHeader>(inputFile);
|
||||
if (HeaderSettings.Version is not "3")
|
||||
{
|
||||
throw new FileLoadException($"Not a valid N4 file: Version doesn't match, got {HeaderSettings.Version} instead of 3)", FileFullPath);
|
||||
@@ -524,7 +528,24 @@ public sealed class AnetN4File : FileFormat
|
||||
{
|
||||
Parallel.ForEach(batch, CoreSettings.GetParallelOptions(progress), layerIndex =>
|
||||
{
|
||||
using var mat = layersDefinitions[layerIndex].Decode();
|
||||
using var mat = layersDefinitions[layerIndex].Decode(out var resolutionX, out var resolutionY);
|
||||
if (layerIndex == 0) // Set file resolution from first layer RLE. Figure out other properties after that
|
||||
{
|
||||
ResolutionX = resolutionX;
|
||||
ResolutionY = resolutionY;
|
||||
|
||||
var machine = Machine.Machines.FirstOrDefault(machine =>
|
||||
machine.Brand == PrinterBrand.Anet && machine.ResolutionX == resolutionX &&
|
||||
machine.ResolutionY == resolutionY);
|
||||
|
||||
if (machine is not null)
|
||||
{
|
||||
DisplayWidth = machine.DisplayWidth;
|
||||
DisplayHeight = machine.DisplayHeight;
|
||||
MachineZ = machine.MachineZ;
|
||||
MachineName = machine.Name;
|
||||
}
|
||||
}
|
||||
_layers[layerIndex] = new Layer((uint)layerIndex, mat, this);
|
||||
progress.LockAndIncrement();
|
||||
});
|
||||
@@ -374,6 +374,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
new PHZFile(), // phz
|
||||
new PhotonWorkshopFile(), // PSW
|
||||
new CWSFile(), // CWS
|
||||
new AnetFile(), // Anet N4, N7
|
||||
new LGSFile(), // LGS, LGS30
|
||||
new VDAFile(), // VDA
|
||||
new VDTFile(), // VDT
|
||||
@@ -385,7 +386,6 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
new ZCodexFile(), // zcodex
|
||||
new MDLPFile(), // MKS v1
|
||||
new GR1File(), // GR1 Workshop
|
||||
new AnetN4File(), // N4
|
||||
new FlashForgeSVGXFile(), // SVGX
|
||||
new OSLAFile(), // OSLA
|
||||
new OSFFile(), // OSF
|
||||
@@ -979,6 +979,11 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
private bool _haveModifiedLayers;
|
||||
private uint _version;
|
||||
|
||||
private uint _resolutionX;
|
||||
private uint _resolutionY;
|
||||
private float _displayWidth;
|
||||
private float _displayHeight;
|
||||
|
||||
private byte _antiAliasing = 1;
|
||||
|
||||
private ushort _bottomLayerCount = DefaultBottomLayerCount;
|
||||
@@ -1157,6 +1162,13 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
|
||||
public string? DirectoryPath => Path.GetDirectoryName(FileFullPath);
|
||||
public string? Filename => Path.GetFileName(FileFullPath);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file extension. The returned value includes the period (".") character of the
|
||||
/// extension except when you have a terminal period when you get string.Empty, such as ".exe" or ".cpp".
|
||||
/// The returned value is null if the given path is null or empty if the given path does not include an
|
||||
/// extension.
|
||||
/// </summary>
|
||||
public string? FileExtension => Path.GetExtension(FileFullPath);
|
||||
public string? FilenameNoExt => GetFileNameStripExtensions(FileFullPath);
|
||||
|
||||
@@ -1512,34 +1524,34 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
ResolutionX = (uint) value.Width;
|
||||
ResolutionY = (uint) value.Height;
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(ResolutionRectangle));
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatio));
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatioStr));
|
||||
RaisePropertyChanged(nameof(Xppmm));
|
||||
RaisePropertyChanged(nameof(Yppmm));
|
||||
RaisePropertyChanged(nameof(Ppmm));
|
||||
RaisePropertyChanged(nameof(PpmmMax));
|
||||
RaisePropertyChanged(nameof(PixelSizeMicrons));
|
||||
RaisePropertyChanged(nameof(PixelArea));
|
||||
RaisePropertyChanged(nameof(PixelAreaMicrons));
|
||||
RaisePropertyChanged(nameof(PixelHeight));
|
||||
RaisePropertyChanged(nameof(PixelHeightMicrons));
|
||||
RaisePropertyChanged(nameof(PixelSize));
|
||||
RaisePropertyChanged(nameof(PixelSizeMax));
|
||||
RaisePropertyChanged(nameof(PixelWidth));
|
||||
RaisePropertyChanged(nameof(PixelWidthMicrons));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image width resolution
|
||||
/// </summary>
|
||||
public abstract uint ResolutionX { get; set; }
|
||||
public virtual uint ResolutionX
|
||||
{
|
||||
get => _resolutionX;
|
||||
set
|
||||
{
|
||||
if(!RaiseAndSetIfChanged(ref _resolutionX, value)) return;
|
||||
NotifyAspectChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image height resolution
|
||||
/// </summary>
|
||||
public abstract uint ResolutionY { get; set; }
|
||||
public virtual uint ResolutionY
|
||||
{
|
||||
get => _resolutionY;
|
||||
set
|
||||
{
|
||||
if(!RaiseAndSetIfChanged(ref _resolutionY, value)) return;
|
||||
NotifyAspectChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an rectangle that starts at 0,0 and goes up to <see cref="Resolution"/>
|
||||
@@ -1562,34 +1574,34 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
DisplayWidth = (float)Math.Round(value.Width, 4);
|
||||
DisplayHeight = (float)Math.Round(value.Height, 4);
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatio));
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatioStr));
|
||||
RaisePropertyChanged(nameof(DisplayDiagonal));
|
||||
RaisePropertyChanged(nameof(DisplayDiagonalInches));
|
||||
RaisePropertyChanged(nameof(Xppmm));
|
||||
RaisePropertyChanged(nameof(Yppmm));
|
||||
RaisePropertyChanged(nameof(Ppmm));
|
||||
RaisePropertyChanged(nameof(PpmmMax));
|
||||
RaisePropertyChanged(nameof(PixelSizeMicrons));
|
||||
RaisePropertyChanged(nameof(PixelArea));
|
||||
RaisePropertyChanged(nameof(PixelAreaMicrons));
|
||||
RaisePropertyChanged(nameof(PixelHeight));
|
||||
RaisePropertyChanged(nameof(PixelHeightMicrons));
|
||||
RaisePropertyChanged(nameof(PixelSize));
|
||||
RaisePropertyChanged(nameof(PixelSizeMax));
|
||||
RaisePropertyChanged(nameof(PixelWidth));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display width in millimeters
|
||||
/// </summary>
|
||||
public virtual float DisplayWidth { get; set; }
|
||||
public virtual float DisplayWidth
|
||||
{
|
||||
get => _displayWidth;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _displayWidth, value)) return;
|
||||
NotifyAspectChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display height in millimeters
|
||||
/// </summary>
|
||||
public virtual float DisplayHeight { get; set; }
|
||||
public virtual float DisplayHeight
|
||||
{
|
||||
get => _displayHeight;
|
||||
set
|
||||
{
|
||||
if(!RaiseAndSetIfChanged(ref _displayHeight, value)) return;
|
||||
NotifyAspectChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display diagonal in millimeters
|
||||
@@ -3207,6 +3219,38 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
|
||||
#endregion
|
||||
|
||||
#region Notification
|
||||
|
||||
/// <summary>
|
||||
/// Raise notification for aspect changes, like <see cref="Resolution"/>, <see cref="Display"/> and relatives
|
||||
/// </summary>
|
||||
protected void NotifyAspectChange()
|
||||
{
|
||||
RaisePropertyChanged(nameof(ResolutionRectangle));
|
||||
RaisePropertyChanged(nameof(DisplayPixelCount));
|
||||
RaisePropertyChanged(nameof(DisplayDiagonal));
|
||||
RaisePropertyChanged(nameof(DisplayDiagonalInches));
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatio));
|
||||
RaisePropertyChanged(nameof(DisplayAspectRatioStr));
|
||||
RaisePropertyChanged(nameof(IsDisplayPortrait));
|
||||
RaisePropertyChanged(nameof(IsDisplayLandscape));
|
||||
RaisePropertyChanged(nameof(Xppmm));
|
||||
RaisePropertyChanged(nameof(Yppmm));
|
||||
RaisePropertyChanged(nameof(Ppmm));
|
||||
RaisePropertyChanged(nameof(PpmmMax));
|
||||
RaisePropertyChanged(nameof(PixelSizeMicrons));
|
||||
RaisePropertyChanged(nameof(PixelArea));
|
||||
RaisePropertyChanged(nameof(PixelAreaMicrons));
|
||||
RaisePropertyChanged(nameof(PixelSizeMicronsMax));
|
||||
RaisePropertyChanged(nameof(PixelHeight));
|
||||
RaisePropertyChanged(nameof(PixelHeightMicrons));
|
||||
RaisePropertyChanged(nameof(PixelSize));
|
||||
RaisePropertyChanged(nameof(PixelSizeMax));
|
||||
RaisePropertyChanged(nameof(PixelWidth));
|
||||
RaisePropertyChanged(nameof(PixelWidthMicrons));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Clears all definitions and properties, it also dispose valid candidates
|
||||
|
||||
@@ -65,6 +65,8 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
private Rectangle _boundingRectangle = Rectangle.Empty;
|
||||
private bool _isModified;
|
||||
private uint _index;
|
||||
private uint _resolutionX;
|
||||
private uint _resolutionY;
|
||||
private float _positionZ;
|
||||
private float _lightOffDelay;
|
||||
private float _waitTimeBeforeCure;
|
||||
@@ -90,6 +92,38 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
/// </summary>
|
||||
public FileFormat SlicerFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Image resolution X
|
||||
/// </summary>
|
||||
public uint ResolutionX
|
||||
{
|
||||
get => _resolutionX;
|
||||
set => RaiseAndSetIfChanged(ref _resolutionX, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Image resolution Y
|
||||
/// </summary>
|
||||
public uint ResolutionY
|
||||
{
|
||||
get => _resolutionY;
|
||||
set => RaiseAndSetIfChanged(ref _resolutionY, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Image resolution
|
||||
/// </summary>
|
||||
public Size Resolution
|
||||
{
|
||||
get => new((int)ResolutionX, (int)ResolutionY);
|
||||
set
|
||||
{
|
||||
ResolutionX = (uint)value.Width;
|
||||
ResolutionY = (uint)value.Height;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of non zero pixels on this layer image
|
||||
/// </summary>
|
||||
@@ -182,12 +216,12 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
/// <summary>
|
||||
/// Gets the first pixel index on this layer
|
||||
/// </summary>
|
||||
public uint FirstPixelIndex => (uint)(BoundingRectangle.Y * SlicerFile.ResolutionX + BoundingRectangle.X);
|
||||
public uint FirstPixelIndex => (uint)(BoundingRectangle.Y * ResolutionX + BoundingRectangle.X);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last pixel index on this layer
|
||||
/// </summary>
|
||||
public uint LastPixelIndex => (uint)(BoundingRectangle.Bottom * SlicerFile.ResolutionX + BoundingRectangle.Right);
|
||||
public uint LastPixelIndex => (uint)(BoundingRectangle.Bottom * ResolutionX + BoundingRectangle.Right);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first pixel <see cref="Point"/> on this layer
|
||||
@@ -801,12 +835,12 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
CvInvoke.Imdecode(_compressedBytes, ImreadModes.Grayscale, mat);
|
||||
break;
|
||||
case LayerCompressionCodec.Lz4:
|
||||
mat = SlicerFile.CreateMat(false);
|
||||
mat = new Mat(Resolution, DepthType.Cv8U, 1);
|
||||
LZ4Codec.Decode(_compressedBytes.AsSpan(), mat.GetDataByteSpan());
|
||||
break;
|
||||
case LayerCompressionCodec.GZip:
|
||||
{
|
||||
mat = SlicerFile.CreateMat(false);
|
||||
mat = new Mat(Resolution, DepthType.Cv8U, 1);
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pBuffer = _compressedBytes)
|
||||
@@ -822,7 +856,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
}
|
||||
case LayerCompressionCodec.Deflate:
|
||||
{
|
||||
mat = SlicerFile.CreateMat(false);
|
||||
mat = new Mat(Resolution, DepthType.Cv8U, 1);
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pBuffer = _compressedBytes)
|
||||
@@ -837,7 +871,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
break;
|
||||
}
|
||||
/*case LayerCompressionMethod.None:
|
||||
mat = new(SlicerFile.Resolution, DepthType.Cv8U, 1);
|
||||
mat = new Mat(Resolution, DepthType.Cv8U, 1);
|
||||
//mat.SetBytes(_compressedBytes!);
|
||||
_compressedBytes.CopyTo(mat.GetDataByteSpan());
|
||||
break;*/
|
||||
@@ -852,8 +886,15 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
if (value is not null)
|
||||
{
|
||||
CompressedBytes = CompressMat(value, _compressionCodec);
|
||||
_resolutionX = (uint)value.Width;
|
||||
_resolutionY = (uint)value.Height;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_resolutionX = 0;
|
||||
_resolutionY = 0;
|
||||
}
|
||||
|
||||
GetBoundingRectangle(value, true);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
@@ -997,6 +1038,9 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
|
||||
SlicerFile = slicerFile;
|
||||
_index = index;
|
||||
|
||||
_resolutionX = slicerFile.ResolutionX;
|
||||
_resolutionY = slicerFile.ResolutionY;
|
||||
|
||||
//if (slicerFile is null) return;
|
||||
_positionZ = SlicerFile.GetHeightFromLayer(index);
|
||||
@@ -1647,6 +1691,8 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
public void CopyImageTo(Layer layer)
|
||||
{
|
||||
if (!HaveImage) return;
|
||||
layer.ResolutionX = _resolutionX;
|
||||
layer.ResolutionY = _resolutionY;
|
||||
layer.CompressedBytes = _compressedBytes?.ToArray();
|
||||
layer.BoundingRectangle = _boundingRectangle;
|
||||
layer.NonZeroPixelCount = _nonZeroPixelCount;
|
||||
|
||||
@@ -213,6 +213,7 @@ namespace UVtools.Core.Printer
|
||||
new(PrinterBrand.Creality, "CT-005 Pro", "CT-005", 3840, 2400, 192, 120, 250),*/
|
||||
|
||||
new(PrinterBrand.Anet, "Anet N4", "N4", 1440, 2560, 68.04f, 120.96f, 135f, FlipDirection.Horizontally),
|
||||
new(PrinterBrand.Anet, "Anet N7", "N7", 2560, 1600, 192f, 120f, 300f, FlipDirection.Horizontally),
|
||||
|
||||
new(PrinterBrand.AnyCubic, "AnyCubic Photon M3", "Photon M3", 4096, 2560, 163.84f, 102.40f, 180f, FlipDirection.Horizontally),
|
||||
new(PrinterBrand.AnyCubic, "AnyCubic Photon M3 Max", "Photon M3 Max", 6480, 3600, 298.08f, 165.60f, 300f, FlipDirection.Horizontally),
|
||||
|
||||
@@ -1371,19 +1371,19 @@
|
||||
<param name="mode"></param>
|
||||
<returns>Created <see cref="T:System.IO.Compression.ZipArchiveEntry"/></returns>
|
||||
</member>
|
||||
<member name="T:UVtools.Core.FileFormats.AnetN4File">
|
||||
<member name="T:UVtools.Core.FileFormats.AnetFile">
|
||||
<summary>
|
||||
This file format is based on B9Creator job file (.b9j) with defined version = 3
|
||||
and added several new fields (as example, preview image).
|
||||
Some of the format features are not recommended to use (BaseLayersCount and FilledBaseLayersCount).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:UVtools.Core.FileFormats.AnetN4File.BmpHeader">
|
||||
<member name="F:UVtools.Core.FileFormats.AnetFile.BmpHeader">
|
||||
<summary>
|
||||
Printer uses incorrect BMP header for preview image so we need to use it as-is instead of generating.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.FileFormats.AnetN4File.LayerDef.WhitePixelsCount">
|
||||
<member name="P:UVtools.Core.FileFormats.AnetFile.LayerDef.WhitePixelsCount">
|
||||
<summary>
|
||||
White pixels region (border including corner pixels)
|
||||
</summary>
|
||||
@@ -2373,6 +2373,14 @@
|
||||
Gets the input file path loaded into this <see cref="T:UVtools.Core.FileFormats.FileFormat"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.FileFormats.FileFormat.FileExtension">
|
||||
<summary>
|
||||
Returns the file extension. The returned value includes the period (".") character of the
|
||||
extension except when you have a terminal period when you get string.Empty, such as ".exe" or ".cpp".
|
||||
The returned value is null if the given path is null or empty if the given path does not include an
|
||||
extension.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.FileFormats.FileFormat.AvailableVersions">
|
||||
<summary>
|
||||
Gets the available versions to set in this file format
|
||||
@@ -3104,6 +3112,11 @@
|
||||
<param name="index">Layer index</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:UVtools.Core.FileFormats.FileFormat.NotifyAspectChange">
|
||||
<summary>
|
||||
Raise notification for aspect changes, like <see cref="P:UVtools.Core.FileFormats.FileFormat.Resolution"/>, <see cref="P:UVtools.Core.FileFormats.FileFormat.Display"/> and relatives
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:UVtools.Core.FileFormats.FileFormat.Clear">
|
||||
<summary>
|
||||
Clears all definitions and properties, it also dispose valid candidates
|
||||
@@ -4763,6 +4776,21 @@
|
||||
Gets or sets the parent SlicerFile
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.Layers.Layer.ResolutionX">
|
||||
<summary>
|
||||
Image resolution X
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.Layers.Layer.ResolutionY">
|
||||
<summary>
|
||||
Image resolution Y
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.Layers.Layer.Resolution">
|
||||
<summary>
|
||||
Image resolution
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:UVtools.Core.Layers.Layer.NonZeroPixelCount">
|
||||
<summary>
|
||||
Gets the number of non zero pixels on this layer image
|
||||
|
||||
Reference in New Issue
Block a user