mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-08 17:42:31 +02:00
v3.5.3
- (Add) Layer action - Export layers to HTML: Export file information and layers to an html file - (Change) CXDLP: Validate header and footer value must start with "CXSW3D" instead of force equal to "CXSW3DV2" (#501) - (Upgrade) .NET from 6.0.5 to 6.0.6
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 07/07/2022 - v3.5.3
|
||||
|
||||
- (Add) Layer action - Export layers to HTML: Export file information and layers to an html file
|
||||
- (Change) CXDLP: Validate header and footer value must start with "CXSW3D" instead of force equal to "CXSW3DV2" (#501)
|
||||
- (Upgrade) .NET from 6.0.5 to 6.0.6
|
||||
|
||||
## 25/06/2022 - v3.5.2
|
||||
|
||||
- **PCB Exposure:**
|
||||
|
||||
+3
-5
@@ -1,6 +1,4 @@
|
||||
- **PCB Exposure:**
|
||||
- (Add) Gerber file extensions: gko, gtl, gto, gts, gbl, gbo, gbs, gml
|
||||
- (Fix) Trailing zeros suppression mode and improve the parsing of the coordinate string (#492)
|
||||
- (Fix) Allow coordinates without number `XYD0*` to indicate `X=0` and `Y=0`
|
||||
- (Fix) Do not try to fetch apertures lower than index 10 when a `D02` (closed shutter) is found alone
|
||||
- (Add) Layer action - Export layers to HTML: Export file information and layers to an html file
|
||||
- (Change) CXDLP: Validate header and footer value must start with "CXSW3D" instead of force equal to "CXSW3DV2" (#501)
|
||||
- (Upgrade) .NET from 6.0.5 to 6.0.6
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 872 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 8.1 KiB |
@@ -35,6 +35,7 @@ public class CXDLPFile : FileFormat
|
||||
#region Constants
|
||||
private const byte HEADER_SIZE = 9; // CXSW3DV2
|
||||
private const string HEADER_VALUE = "CXSW3DV2";
|
||||
private const string HEADER_VALUE_GENERIC = "CXSW3D";
|
||||
#endregion
|
||||
|
||||
#region Sub Classes
|
||||
@@ -128,9 +129,14 @@ public class CXDLPFile : FileFormat
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (HeaderSize != HEADER_SIZE || HeaderValue != HEADER_VALUE)
|
||||
/*if (HeaderSize != HEADER_SIZE || HeaderValue != HEADER_VALUE)
|
||||
{
|
||||
throw new FileLoadException("Not a valid CXDLP file!");
|
||||
}*/
|
||||
|
||||
if (HeaderSize - 1 != HeaderValue.Length || !HeaderValue.StartsWith(HEADER_VALUE_GENERIC))
|
||||
{
|
||||
throw new FileLoadException($"Invalid header data for CXDLP file.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,11 +392,21 @@ public class CXDLPFile : FileFormat
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (FooterSize != HEADER_SIZE || FooterValue != HEADER_VALUE)
|
||||
/*if (FooterSize != HEADER_SIZE || FooterValue != HEADER_VALUE)
|
||||
{
|
||||
throw new FileLoadException("Not a valid CXDLP file!");
|
||||
throw new FileLoadException($"Not a valid CXDLP file! Incorrect footer data.\n{ToString()}");
|
||||
}*/
|
||||
|
||||
if (FooterSize-1 != FooterValue.Length || !FooterValue.StartsWith(HEADER_VALUE_GENERIC))
|
||||
{
|
||||
throw new FileLoadException($"Invalid footer data for CXDLP file.\n{ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(FooterSize)}: {FooterSize}, {nameof(FooterValue)}: {FooterValue}";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* Version 3, 19 November 2007
|
||||
* Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Emgu.CV;
|
||||
using Emgu.CV.CvEnum;
|
||||
using UVtools.Core.EmguCV;
|
||||
using UVtools.Core.Extensions;
|
||||
using UVtools.Core.FileFormats;
|
||||
|
||||
namespace UVtools.Core.Operations;
|
||||
|
||||
[Serializable]
|
||||
public sealed class OperationLayerExportHtml : Operation
|
||||
{
|
||||
#region Members
|
||||
private string _filePath = null!;
|
||||
private bool _exportThumbnails = true;
|
||||
private bool _exportLayerSettings = true;
|
||||
private bool _exportGCode = true;
|
||||
private bool _exportLayerPreview = true;
|
||||
private bool _exportRawData = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
public override LayerRangeSelection StartLayerRangeSelection => LayerRangeSelection.None;
|
||||
|
||||
public override bool CanROI => false;
|
||||
public override bool CanMask => false;
|
||||
|
||||
public override string IconClass => "fa-brands fa-html5";
|
||||
public override string Title => "Export layers to HTML";
|
||||
|
||||
public override string Description =>
|
||||
"Export file information and layers to an html file.\n";
|
||||
|
||||
public override string ConfirmationText =>
|
||||
$"export layers {LayerIndexStart} through {LayerIndexEnd}?";
|
||||
|
||||
public override string ProgressTitle =>
|
||||
$"Exporting layers {LayerIndexStart} through {LayerIndexEnd}";
|
||||
|
||||
public override string ProgressAction => "Exported layers";
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = $"[Thumbnails: {_exportThumbnails}]" +
|
||||
$" [Raw data: {_exportRawData}]" +
|
||||
$" [Layers: {_exportLayerSettings}]" +
|
||||
$" [GCode: {_exportGCode}]" +
|
||||
$" [Preview: {_exportLayerPreview}]";
|
||||
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string FilePath
|
||||
{
|
||||
get => _filePath;
|
||||
set => RaiseAndSetIfChanged(ref _filePath, value);
|
||||
}
|
||||
|
||||
public bool ExportThumbnails
|
||||
{
|
||||
get => _exportThumbnails;
|
||||
set => RaiseAndSetIfChanged(ref _exportThumbnails, value);
|
||||
}
|
||||
|
||||
public bool ExportRawData
|
||||
{
|
||||
get => _exportRawData;
|
||||
set => RaiseAndSetIfChanged(ref _exportRawData, value);
|
||||
}
|
||||
|
||||
public bool ExportLayerSettings
|
||||
{
|
||||
get => _exportLayerSettings;
|
||||
set => RaiseAndSetIfChanged(ref _exportLayerSettings, value);
|
||||
}
|
||||
|
||||
public bool ExportGCode
|
||||
{
|
||||
get => _exportGCode;
|
||||
set => RaiseAndSetIfChanged(ref _exportGCode, value);
|
||||
}
|
||||
|
||||
public bool ExportLayerPreview
|
||||
{
|
||||
get => _exportLayerPreview;
|
||||
set => RaiseAndSetIfChanged(ref _exportLayerPreview, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public OperationLayerExportHtml()
|
||||
{ }
|
||||
|
||||
public OperationLayerExportHtml(FileFormat slicerFile) : base(slicerFile)
|
||||
{ }
|
||||
|
||||
public override void InitWithSlicerFile()
|
||||
{
|
||||
_filePath = SlicerFile.FileFullPath + ".html";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override bool ExecuteInternally(OperationProgress progress)
|
||||
{
|
||||
using TextWriter html = new StreamWriter(_filePath);
|
||||
html.WriteLine("<!doctype html>");
|
||||
html.WriteLine("<html lang=\"en\" class=\"h-100\">");
|
||||
html.WriteLine(" <head>");
|
||||
html.WriteLine(" <meta charset=\"utf-8\">");
|
||||
html.WriteLine(" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
|
||||
html.WriteLine($" <meta name=\"description\" content=\"{About.SoftwareWithVersion}\">");
|
||||
html.WriteLine($" <meta name=\"author\" content=\"{About.SoftwareWithVersion}\">");
|
||||
html.WriteLine($" <meta name=\"generator\" content=\"{About.SoftwareWithVersion}\">");
|
||||
html.WriteLine($" <title>{About.Software} · {SlicerFile.Filename}</title>");
|
||||
html.WriteLine();
|
||||
html.WriteLine($" <link rel=\"UVtools\" href=\"{About.Website}\">");
|
||||
html.WriteLine($" <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwpJREFUeNrsV01IG0EU/pJILFJxIRCqeFi8BQkMBARPDQqCp20FpbfUgJ5EUfBsDQTEi8ab5pB6LKLGk61iY045RdaTIBo25lAbsKwI2gZCOzNJ1vy4mxTUpdDvseyb2WTeN+9vdywoYhzjXnqbotcbPC2i9AqtYe2QDSxF4+/pLYLnxTIlMW0p7jwGc/DWWnS7WZhjBLwmEiCMgGAiAVhhMv4T0CVwQ0UPuaI0iisqDRNghgciAwimgpC2JUCsfC76REweTfKL6UbIC3m+RvhHmK/JxtVoqp5w+9wY8g0VjIki7tQ77I3uaTtZWFqAIBQKh0QIpHUJ7VQeQs9UDwalQa6zNTNyBiehE2MPOESH7pi5vWS8EVSv1SK01A9Bcj0JVVW18cHywf2CVBLxhDZmOpvTQ2I9UTE+jZ/W/Ia9C35XT94KtwgcBTDbNwuH4qjJEf+2H9fqNTZHN9FKxTAPSB7hozCGu4Zr1nowB7ir1Bak02nklNpMZwZTckrT6yErZwvhU3KNlyHzQFtbG5zE+WB5sth2kS7DUi3BLtr5vZN0NkiAVtZKagWEEO46p+SsSMKJ2ATP6H6pn+tG/aDV24qN1AbXg1+DsBFb/RB4fJ6KTPcv+bFP9rn+i0rv617tGdMXqOiVoUtyaTpbk0gESTlpTOBKqexa58fnWvYyAqxCygkyI9mdLOxUvlF5SYXnBvWki7gqQ6ve1pC0eeD5UD6ROc7AIlrQLrYj9iWGrekt5OQcT6K8ksfZ5RmPJyMSng9jZGoE3e+60Uyasbi7yD2oCipmIjOIrkZx8f0CbuLG7s4u4vNxWH9a65dhqevp1Xgp+dhOme6d82Jsbkx7rigKAn0B2JVCAjLP6IWpSbeLGTSY8vJjenWDYSVcMs6gZ/zRXseqrOJEvu/xiY+Jhv+rG4K/BQtFh7eDJ3H57uuh6bE+LHg+HN7wavjnvohUswlETbQfZQRCJhII2ZJIXtJumC6ekF48o/FRejiN8tcTJSFTEp/KTkmvnsioTK/P7FBaOp7/EWAAocsV0JqWvDkAAAAASUVORK5CYII=\" />");
|
||||
|
||||
html.WriteLine($" <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor\" crossorigin=\"anonymous\">");
|
||||
html.WriteLine(" <style>");
|
||||
// Start Styles
|
||||
html.WriteLine(" main > .container {padding: 30px 0 50px 0;}");
|
||||
html.WriteLine(" .table > thead > tr > th, .table > tbody > tr > td {vertical-align: middle;}");
|
||||
// End Styles
|
||||
html.WriteLine(" </style>");
|
||||
html.WriteLine(" </head>");
|
||||
html.WriteLine(" <body class=\"d-flex flex-column h-100\">");
|
||||
html.WriteLine();
|
||||
html.WriteLine($" <header>");
|
||||
// Start Navbar
|
||||
html.WriteLine($" <nav class=\"navbar navbar-expand-md navbar-dark fixed-top bg-dark\">");
|
||||
html.WriteLine($" <div class=\"container\">");
|
||||
html.WriteLine($" <a class=\"navbar-brand\" href=\"#\"><img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwpJREFUeNrsV01IG0EU/pJILFJxIRCqeFi8BQkMBARPDQqCp20FpbfUgJ5EUfBsDQTEi8ab5pB6LKLGk61iY045RdaTIBo25lAbsKwI2gZCOzNJ1vy4mxTUpdDvseyb2WTeN+9vdywoYhzjXnqbotcbPC2i9AqtYe2QDSxF4+/pLYLnxTIlMW0p7jwGc/DWWnS7WZhjBLwmEiCMgGAiAVhhMv4T0CVwQ0UPuaI0iisqDRNghgciAwimgpC2JUCsfC76REweTfKL6UbIC3m+RvhHmK/JxtVoqp5w+9wY8g0VjIki7tQ77I3uaTtZWFqAIBQKh0QIpHUJ7VQeQs9UDwalQa6zNTNyBiehE2MPOESH7pi5vWS8EVSv1SK01A9Bcj0JVVW18cHywf2CVBLxhDZmOpvTQ2I9UTE+jZ/W/Ia9C35XT94KtwgcBTDbNwuH4qjJEf+2H9fqNTZHN9FKxTAPSB7hozCGu4Zr1nowB7ir1Bak02nklNpMZwZTckrT6yErZwvhU3KNlyHzQFtbG5zE+WB5sth2kS7DUi3BLtr5vZN0NkiAVtZKagWEEO46p+SsSMKJ2ATP6H6pn+tG/aDV24qN1AbXg1+DsBFb/RB4fJ6KTPcv+bFP9rn+i0rv617tGdMXqOiVoUtyaTpbk0gESTlpTOBKqexa58fnWvYyAqxCygkyI9mdLOxUvlF5SYXnBvWki7gqQ6ve1pC0eeD5UD6ROc7AIlrQLrYj9iWGrekt5OQcT6K8ksfZ5RmPJyMSng9jZGoE3e+60Uyasbi7yD2oCipmIjOIrkZx8f0CbuLG7s4u4vNxWH9a65dhqevp1Xgp+dhOme6d82Jsbkx7rigKAn0B2JVCAjLP6IWpSbeLGTSY8vJjenWDYSVcMs6gZ/zRXseqrOJEvu/xiY+Jhv+rG4K/BQtFh7eDJ3H57uuh6bE+LHg+HN7wavjnvohUswlETbQfZQRCJhII2ZJIXtJumC6ekF48o/FRejiN8tcTJSFTEp/KTkmvnsioTK/P7FBaOp7/EWAAocsV0JqWvDkAAAAASUVORK5CYII=\" alt=\"\" width=\"32\" height=\"32\" class=\"d-inline-block align-text-top\"> {About.Software}</a>");
|
||||
html.WriteLine($" <button class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarCollapse\" aria-controls=\"navbarCollapse\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">");
|
||||
html.WriteLine($" <span class=\"navbar-toggler-icon\"></span>");
|
||||
html.WriteLine($" </button>");
|
||||
html.WriteLine($" <div class=\"collapse navbar-collapse\" id=\"navbarCollapse\">");
|
||||
html.WriteLine($" <ul class=\"navbar-nav me-auto mb-2 mb-md-0\">");
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#Information\">Information</a>");
|
||||
html.WriteLine($" </li>");
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#Settings\">Settings</a>");
|
||||
html.WriteLine($" </li>");
|
||||
|
||||
if (_exportRawData && SlicerFile.Configs?.Length > 0)
|
||||
{
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#RawData\">Raw data</a>");
|
||||
html.WriteLine($" </li>");
|
||||
}
|
||||
|
||||
if (_exportLayerSettings && SlicerFile.PrintParameterPerLayerModifiers is not null)
|
||||
{
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#Layers\">Layers</a>");
|
||||
html.WriteLine($" </li>");
|
||||
}
|
||||
|
||||
if (_exportGCode && SlicerFile.HaveGCode)
|
||||
{
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#GCode\">GCode</a>");
|
||||
html.WriteLine($" </li>");
|
||||
}
|
||||
|
||||
if (_exportLayerPreview)
|
||||
{
|
||||
html.WriteLine($" <li class=\"nav-item\">");
|
||||
html.WriteLine($" <a class=\"nav-link\" href=\"#LayerPreview\">Preview</a>");
|
||||
html.WriteLine($" </li>");
|
||||
}
|
||||
|
||||
html.WriteLine($" </ul>");
|
||||
html.WriteLine($" <span class=\"navbar-text\">{SlicerFile.Filename}</span>");
|
||||
html.WriteLine($" </div>");
|
||||
// End Navbar
|
||||
html.WriteLine($" </div>");
|
||||
html.WriteLine($" </nav>");
|
||||
// Start Header
|
||||
// End Header
|
||||
html.WriteLine($" </header>");
|
||||
html.WriteLine();
|
||||
html.WriteLine(" <div class=\"p-5 bg-light rounded-3\">");
|
||||
html.WriteLine(" <div class=\"container pt-5\">");
|
||||
html.WriteLine($" <h1 class=\"display-5 fw-bold\">{SlicerFile.Filename}</h1>");
|
||||
|
||||
if (_exportThumbnails)
|
||||
{
|
||||
var thumbnailCount = 0;
|
||||
foreach (var thumbnail in SlicerFile.Thumbnails)
|
||||
{
|
||||
if (thumbnail is null) continue;
|
||||
thumbnailCount++;
|
||||
html.WriteLine($" <img src=\"data:image/png;base64,{Convert.ToBase64String(thumbnail.GetPngByes())}\" class=\"img-thumbnail\" alt=\"Thumbnail {thumbnailCount}\">");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine();
|
||||
html.WriteLine(" <main class=\"flex-shrink-0\">");
|
||||
html.WriteLine(" <div class=\"container\">");
|
||||
// Start Content
|
||||
|
||||
|
||||
|
||||
html.WriteLine(" <div class=\"accordion\" id=\"accordionStructure\">");
|
||||
html.WriteLine(" <div class=\"accordion-item\">");
|
||||
html.WriteLine(" <h2 class=\"accordion-header\" id=\"accordionStructure-InformationHeader\">");
|
||||
html.WriteLine(" <a id=\"Information\"></a>");
|
||||
html.WriteLine(" <button class=\"accordion-button\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#accordionStructure-Information\" aria-expanded=\"true\" aria-controls=\"accordionStructure-Information\">");
|
||||
html.WriteLine(" <h1>Information</h1>");
|
||||
html.WriteLine(" </button>");
|
||||
html.WriteLine(" </h2>");
|
||||
|
||||
html.WriteLine(" <div id=\"accordionStructure-Information\" class=\"accordion-collapse collapse show\" aria-labelledby=\"accordionStructure-InformationHeader\">");
|
||||
html.WriteLine(" <div class=\"accordion-body\" style=\"padding:0\">");
|
||||
html.WriteLine(" <table class=\"table table-bordered table-striped table-hover table-fluid\">");
|
||||
html.WriteLine(" <thead>");
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine(" <th scope=\"col\">Property</th>");
|
||||
html.WriteLine(" <th scope=\"col\">Value</th>");
|
||||
html.WriteLine(" </tr>");
|
||||
html.WriteLine(" </thead>");
|
||||
html.WriteLine(" <tbody class=\"table-group-divider\">");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Class</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.GetType().Name}, Version: {SlicerFile.Version}</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Image resolution</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.Resolution} px</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
if (SlicerFile.DisplayWidth > 0 && SlicerFile.DisplayHeight > 0)
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Display size</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.Display} mm</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Pixel size</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.PixelSizeMicrons} µm</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Pixels per millimeters</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.Ppmm} px</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Print time</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.PrintTimeString}</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
|
||||
if (SlicerFile.MaterialMilliliters > 0)
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Material milliliters</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.MaterialMilliliters} ml</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
|
||||
if (SlicerFile.MaterialCost > 0)
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Material cost</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.MaterialCost} $</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(SlicerFile.MaterialName))
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Material name</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.MaterialName}</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(SlicerFile.MachineName))
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Machine name</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.MachineName}</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Layer count</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.LayerCount} layers</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Layer height</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.LayerHeight} mm</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Print height</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.PrintHeight} mm</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Print bounding rectangle</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.BoundingRectangleMillimeters} mm</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">Print volume</td>");
|
||||
html.WriteLine($" <td>{SlicerFile.Volume} mm³</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
|
||||
|
||||
html.WriteLine(" </tbody>");
|
||||
html.WriteLine(" </table>");
|
||||
|
||||
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
|
||||
|
||||
|
||||
if (SlicerFile.PrintParameterModifiers is not null)
|
||||
{
|
||||
html.WriteLine(" <div class=\"accordion-item\">");
|
||||
html.WriteLine(" <h2 class=\"accordion-header\" id=\"accordionStructure-SettingsHeader\">");
|
||||
html.WriteLine(" <a id=\"Settings\"></a>");
|
||||
html.WriteLine(" <button class=\"accordion-button\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#accordionStructure-Settings\" aria-expanded=\"true\" aria-controls=\"accordionStructure-Settings\">");
|
||||
html.WriteLine(" <h1>Settings</h1>");
|
||||
html.WriteLine(" </button>");
|
||||
html.WriteLine(" </h2>");
|
||||
|
||||
html.WriteLine(" <div id=\"accordionStructure-Settings\" class=\"accordion-collapse collapse show\" aria-labelledby=\"accordionStructure-SettingsHeader\">");
|
||||
html.WriteLine(" <div class=\"accordion-body\" style=\"padding:0\">");
|
||||
|
||||
html.WriteLine(" <table class=\"table table-bordered table-striped table-hover table-fluid\">");
|
||||
html.WriteLine(" <thead>");
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine(" <th scope=\"col\">Property</th>");
|
||||
html.WriteLine(" <th scope=\"col\">Value</th>");
|
||||
html.WriteLine(" </tr>");
|
||||
html.WriteLine(" </thead>");
|
||||
html.WriteLine(" <tbody class=\"table-group-divider\">");
|
||||
SlicerFile.RefreshPrintParametersModifiersValues();
|
||||
foreach (var modifier in SlicerFile.PrintParameterModifiers)
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\" data-bs-toggle=\"tooltip\" title=\"{modifier.Description}\">{modifier.Name}</td>");
|
||||
html.WriteLine($" <td>{modifier.Value.ToString($"F{modifier.DecimalPlates}")} {modifier.ValueUnit}</td>");
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
}
|
||||
html.WriteLine(" </tbody>");
|
||||
html.WriteLine(" </table>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
}
|
||||
|
||||
|
||||
if (_exportRawData && SlicerFile.Configs?.Length > 0)
|
||||
{
|
||||
html.WriteLine(" <div class=\"accordion-item\">");
|
||||
html.WriteLine(" <h2 class=\"accordion-header\" id=\"accordionStructure-RawDataHeader\">");
|
||||
html.WriteLine(" <a id=\"RawData\"></a>");
|
||||
html.WriteLine(" <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#accordionStructure-RawData\" aria-expanded=\"false\" aria-controls=\"accordionStructure-RawData\">");
|
||||
html.WriteLine(" <h1>Raw data</h1>");
|
||||
html.WriteLine(" </button>");
|
||||
html.WriteLine(" </h2>");
|
||||
|
||||
html.WriteLine(" <div id=\"accordionStructure-RawData\" class=\"accordion-collapse collapse\" aria-labelledby=\"accordionStructure-RawDataHeader\">");
|
||||
html.WriteLine(" <div class=\"accordion-body\" style=\"padding:0\">");
|
||||
|
||||
html.WriteLine(" <table class=\"table table-bordered table-striped table-hover table-fluid\">");
|
||||
html.WriteLine(" <thead>");
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine(" <th scope=\"col\">Class</th>");
|
||||
html.WriteLine(" <th scope=\"col\">Property</th>");
|
||||
html.WriteLine(" <th scope=\"col\">Value</th>");
|
||||
html.WriteLine(" </tr>");
|
||||
html.WriteLine(" </thead>");
|
||||
html.WriteLine(" <tbody class=\"table-group-divider\">");
|
||||
|
||||
foreach (var config in SlicerFile.Configs)
|
||||
{
|
||||
var type = config.GetType();
|
||||
foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (property.Name.Equals("Item")) continue;
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td>{type.Name}</td>");
|
||||
html.WriteLine($" <td>{property.Name}</td>");
|
||||
var value = property.GetValue(config);
|
||||
switch (value)
|
||||
{
|
||||
case null:
|
||||
continue;
|
||||
case IList list:
|
||||
html.WriteLine($" <td>{list.Count}</td>");
|
||||
break;
|
||||
default:
|
||||
html.WriteLine($" <td>{value}</td>");
|
||||
break;
|
||||
}
|
||||
|
||||
html.WriteLine(" </tr>");
|
||||
}
|
||||
}
|
||||
|
||||
html.WriteLine(" </tbody>");
|
||||
html.WriteLine(" </table>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
}
|
||||
|
||||
|
||||
if (_exportLayerSettings && SlicerFile.PrintParameterPerLayerModifiers is not null)
|
||||
{
|
||||
html.WriteLine(" <div class=\"accordion-item\">");
|
||||
html.WriteLine(" <h2 class=\"accordion-header\" id=\"accordionStructure-LayersHeader\">");
|
||||
html.WriteLine(" <a id=\"Layers\"></a>");
|
||||
html.WriteLine(" <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#accordionStructure-Layers\" aria-expanded=\"false\" aria-controls=\"accordionStructure-Layers\">");
|
||||
html.WriteLine(" <h1>Layers</h1>");
|
||||
html.WriteLine(" </button>");
|
||||
html.WriteLine(" </h2>");
|
||||
|
||||
html.WriteLine(" <div id=\"accordionStructure-Layers\" class=\"accordion-collapse collapse\" aria-labelledby=\"accordionStructure-LayersHeader\">");
|
||||
html.WriteLine(" <div class=\"accordion-body\" style=\"padding:0\">");
|
||||
|
||||
html.WriteLine(" <table class=\"table table-bordered table-striped table-hover table-responsive\">");
|
||||
html.WriteLine(" <thead>");
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine(" <th scope=\"col\">#</th>");
|
||||
|
||||
foreach (var modifier in SlicerFile.PrintParameterPerLayerModifiers)
|
||||
{
|
||||
html.WriteLine($" <th scope=\"col\">{modifier.Name}</th>");
|
||||
}
|
||||
|
||||
html.WriteLine(" </tr>");
|
||||
html.WriteLine(" </thead>");
|
||||
html.WriteLine(" <tbody class=\"table-group-divider\">");
|
||||
SlicerFile.RefreshPrintParametersModifiersValues();
|
||||
foreach (var layer in SlicerFile)
|
||||
{
|
||||
html.WriteLine(" <tr>");
|
||||
html.WriteLine($" <td scope=\"row\">{layer.Index}</td>");
|
||||
SlicerFile.RefreshPrintParametersPerLayerModifiersValues(layer.Index);
|
||||
|
||||
foreach (var modifier in SlicerFile.PrintParameterPerLayerModifiers)
|
||||
{
|
||||
html.WriteLine($" <td>{modifier.Value.ToString($"F{modifier.DecimalPlates}")} {modifier.ValueUnit}</td>");
|
||||
}
|
||||
|
||||
html.WriteLine(" </tr>");
|
||||
|
||||
}
|
||||
|
||||
html.WriteLine(" </tbody>");
|
||||
html.WriteLine(" </table>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
}
|
||||
|
||||
if (_exportGCode && SlicerFile.HaveGCode)
|
||||
{
|
||||
html.WriteLine(" <div class=\"accordion-item\">");
|
||||
html.WriteLine(" <h2 class=\"accordion-header\" id=\"accordionStructure-GCodeHeader\">");
|
||||
html.WriteLine(" <a id=\"GCode\"></a>");
|
||||
html.WriteLine(" <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#accordionStructure-GCode\" aria-expanded=\"false\" aria-controls=\"accordionStructure-GCode\">");
|
||||
html.WriteLine(" <h1>GCode</h1>");
|
||||
html.WriteLine(" </button>");
|
||||
html.WriteLine(" </h2>");
|
||||
|
||||
html.WriteLine(" <div id=\"accordionStructure-GCode\" class=\"accordion-collapse collapse\" aria-labelledby=\"accordionStructure-GCodeHeader\">");
|
||||
html.WriteLine(" <div class=\"accordion-body\">");
|
||||
|
||||
html.WriteLine(" <pre><code>");
|
||||
html.WriteLine(SlicerFile.GCodeStr);
|
||||
html.WriteLine(" </code></pre>");
|
||||
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </div>");
|
||||
}
|
||||
|
||||
if(_exportLayerPreview)
|
||||
{
|
||||
html.WriteLine($" <a id=\"LayerPreview\"></a>");
|
||||
html.WriteLine($" <h1 class=\"mt-4\">Layer preview</h1>");
|
||||
html.WriteLine($" <table class=\"table table-borderless table-sm align-middle w-100\">");
|
||||
html.WriteLine($" <tbody>");
|
||||
html.WriteLine($" <tr>");
|
||||
html.WriteLine($" <td width=\"30\"><a href=\"javascript:;\" onclick=\"showLayer(0)\">0</a></td>");
|
||||
html.WriteLine($" <td><input type=\"range\" class=\"form-range\" min=\"0\" max=\"{SlicerFile.LastLayerIndex}\" step=\"1\" value=\"0\" id=\"layerIndexSlider\" oninput=\"showLayer(this.value)\"></td>");
|
||||
html.WriteLine($" <td class=\"text-end\" width=\"50\"><a href=\"javascript:;\" onclick=\"showLayer({SlicerFile.LastLayerIndex})\">{SlicerFile.LastLayerIndex}</a></td>");
|
||||
html.WriteLine($" </tr>");
|
||||
html.WriteLine($" <tr>");
|
||||
html.WriteLine($" <td id=\"currentLayerIndexText\" colspan=\"3\" class=\"text-center\">0</td>");
|
||||
html.WriteLine($" </tr>");
|
||||
html.WriteLine($" </tbody>");
|
||||
html.WriteLine($" </table>");
|
||||
|
||||
html.WriteLine($" <svg xmlns=\"http://www.w3.org/2000/svg\" id=\"svgLayer\" viewBox=\"0 0 {SlicerFile.ResolutionX} {SlicerFile.ResolutionY}\">");
|
||||
html.WriteLine(" <defs>");
|
||||
html.WriteLine(" <style>");
|
||||
html.WriteLine(" .background { fill: #000000; }");
|
||||
html.WriteLine(" path { fill: #FFFFFF; fill-rule: evenodd; }");
|
||||
html.WriteLine(" </style>");
|
||||
html.WriteLine(" </defs>");
|
||||
html.WriteLine($" <g id=\"svgLayerGroup\">");
|
||||
html.WriteLine($" <rect class=\"background\" width=\"{SlicerFile.ResolutionX}\" height=\"{SlicerFile.ResolutionY}\"/>");
|
||||
html.WriteLine(" </g>");
|
||||
html.WriteLine(" </svg>");
|
||||
}
|
||||
|
||||
html.WriteLine(" </div>");
|
||||
|
||||
// End Content
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </main>");
|
||||
html.WriteLine();
|
||||
html.WriteLine(" <footer class=\"footer mt-auto py-3 bg-light\">");
|
||||
html.WriteLine(" <div class=\"container\">");
|
||||
// Start Footer
|
||||
html.WriteLine($" <span class=\"text-muted\"><a href=\"{About.Website}\" target=\"_blank\">{About.SoftwareWithVersion}</a> · {SlicerFile.Filename}</span>");
|
||||
html.WriteLine($" <span class=\"text-muted float-end\">{DateTime.Now}</span>");
|
||||
// End Footer
|
||||
html.WriteLine(" </div>");
|
||||
html.WriteLine(" </footer>");
|
||||
html.WriteLine();
|
||||
html.WriteLine(" <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js\" integrity=\"sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2\" crossorigin=\"anonymous\"></script>");
|
||||
html.WriteLine(" <script>");
|
||||
html.WriteLine(" const firstLayerIndex = 0;");
|
||||
html.WriteLine($" const lastLayerIndex = {SlicerFile.LastLayerIndex};");
|
||||
html.WriteLine($" const layerCount = {SlicerFile.LayerCount};");
|
||||
html.WriteLine($" var currentLayerIndex = firstLayerIndex;");
|
||||
html.WriteLine(" const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle=\"tooltip\"]')");
|
||||
html.WriteLine(" const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))");
|
||||
|
||||
|
||||
if (_exportLayerPreview)
|
||||
{
|
||||
html.WriteLine(" const layerSvg = {");
|
||||
|
||||
var layerSvgPath = new string[SlicerFile.LayerCount];
|
||||
Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndex =>
|
||||
{
|
||||
using var mat = SlicerFile[layerIndex].LayerMat;
|
||||
CvInvoke.Threshold(mat, mat, 127, byte.MaxValue, ThresholdType.Binary); // Remove AA
|
||||
|
||||
using var contours = mat.FindContours(out var hierarchy, RetrType.Tree);
|
||||
bool firstTime = true;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendFormat($" {layerIndex}: '");
|
||||
for (int i = 0; i < contours.Size; i++)
|
||||
{
|
||||
if (hierarchy[i, EmguContour.HierarchyParent] == -1) // Top hierarchy
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("\"/>");
|
||||
}
|
||||
|
||||
sb.AppendFormat("<path d=\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat(" ");
|
||||
}
|
||||
|
||||
sb.AppendFormat($"M {contours[i][0].X} {contours[i][0].Y} L");
|
||||
for (int x = 1; x < contours[i].Size; x++)
|
||||
{
|
||||
sb.AppendFormat($" {contours[i][x].X} {contours[i][x].Y}");
|
||||
}
|
||||
sb.AppendFormat(" Z");
|
||||
}
|
||||
|
||||
if (!firstTime) sb.AppendFormat("\"/>");
|
||||
sb.AppendFormat("'");
|
||||
layerSvgPath[layerIndex] = sb.ToString();
|
||||
progress.LockAndIncrement();
|
||||
});
|
||||
|
||||
html.WriteLine($" {string.Join(',', layerSvgPath)}");
|
||||
html.WriteLine(" };");
|
||||
html.WriteLine();
|
||||
html.WriteLine(" function showLayer(layerIndex) {");
|
||||
html.WriteLine(" if(layerIndex < firstLayerIndex) return false;");
|
||||
html.WriteLine(" if(layerIndex > lastLayerIndex) return false;");
|
||||
html.WriteLine($" document.getElementById('svgLayerGroup').innerHTML = '<rect class=\"background\" width=\"{SlicerFile.ResolutionX}\" height=\"{SlicerFile.ResolutionY}\"></rect>' + layerSvg[layerIndex];");
|
||||
html.WriteLine($" document.getElementById('layerIndexSlider').value = layerIndex;");
|
||||
html.WriteLine($" document.getElementById('currentLayerIndexText').innerHTML = layerIndex;");
|
||||
html.WriteLine($" currentLayerIndex = layerIndex;");
|
||||
html.WriteLine(" return true;");
|
||||
html.WriteLine(" }");
|
||||
html.WriteLine(" showLayer(0);");
|
||||
html.WriteLine();
|
||||
}
|
||||
|
||||
|
||||
html.WriteLine(" </script>");
|
||||
html.WriteLine(" </body>");
|
||||
html.WriteLine("</html>");
|
||||
|
||||
return !progress.Token.IsCancellationRequested;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equality
|
||||
|
||||
private bool Equals(OperationLayerExportHtml other)
|
||||
{
|
||||
return _filePath == other._filePath && _exportThumbnails == other._exportThumbnails && _exportLayerSettings == other._exportLayerSettings && _exportGCode == other._exportGCode && _exportLayerPreview == other._exportLayerPreview && _exportRawData == other._exportRawData;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return ReferenceEquals(this, obj) || obj is OperationLayerExportHtml other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_filePath, _exportThumbnails, _exportLayerSettings, _exportGCode, _exportLayerPreview, _exportRawData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
|
||||
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
|
||||
<Version>3.5.2</Version>
|
||||
<Version>3.5.3</Version>
|
||||
<Copyright>Copyright © 2020 PTRTECH</Copyright>
|
||||
<PackageIcon>UVtools.png</PackageIcon>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?define ComponentRules="OneToOne"?>
|
||||
<!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module -->
|
||||
<?define SourceDir="..\publish\UVtools_win-x64_v3.5.2"?>
|
||||
<?define SourceDir="..\publish\UVtools_win-x64_v3.5.3"?>
|
||||
<Module Id="UVtools" Language="1033" Version="1.0.0.0">
|
||||
<Package Id="12aaa1cf-ff06-4a02-abd5-2ac01ac4f83b" Manufacturer="PTRTECH" InstallerVersion="200" Keywords="MSLA, DLP" Description="MSLA/DLP, file analysis, repair, conversion and manipulation" InstallScope="perMachine" Platform="x64" />
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:i="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="UVtools.WPF.Controls.Tools.ToolLayerExportHtmlControl">
|
||||
<StackPanel Spacing="10">
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||
<TextBox Watermark="Output filepath"
|
||||
UseFloatingWatermark="True"
|
||||
VerticalAlignment="Center"
|
||||
IsReadOnly="True"
|
||||
Width="500"
|
||||
Text="{Binding Operation.FilePath}"/>
|
||||
<Button VerticalAlignment="Stretch"
|
||||
Command="{Binding ChooseFilePath}"
|
||||
i:Attached.Icon="fa-solid fa-folder"/>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox Content="Export thumbnails"
|
||||
ToolTip.Tip="If enabled it will export all the available thumbnails"
|
||||
IsChecked="{Binding Operation.ExportThumbnails}"/>
|
||||
|
||||
<CheckBox Content="Export file raw data structure"
|
||||
ToolTip.Tip="If enabled it will export the raw data structure of the file"
|
||||
IsChecked="{Binding Operation.ExportRawData}"/>
|
||||
|
||||
<CheckBox Content="Export layer settings"
|
||||
ToolTip.Tip="If enabled it will export an table with all the layer settings"
|
||||
IsChecked="{Binding Operation.ExportLayerSettings}"/>
|
||||
|
||||
<CheckBox Content="Export GCode"
|
||||
ToolTip.Tip="If enabled it will export the GCode text"
|
||||
IsChecked="{Binding Operation.ExportGCode}"/>
|
||||
|
||||
<CheckBox Content="Export layer preview"
|
||||
ToolTip.Tip="If enabled it will export all the layers images and able to navigate between them but will produce a larger and slower file"
|
||||
IsChecked="{Binding Operation.ExportLayerPreview}"/>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using UVtools.Core.Operations;
|
||||
|
||||
namespace UVtools.WPF.Controls.Tools
|
||||
{
|
||||
public partial class ToolLayerExportHtmlControl : ToolControl
|
||||
{
|
||||
public OperationLayerExportHtml Operation => BaseOperation as OperationLayerExportHtml;
|
||||
public ToolLayerExportHtmlControl()
|
||||
{
|
||||
BaseOperation = new OperationLayerExportHtml(SlicerFile);
|
||||
if (!ValidateSpawn()) return;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public async void ChooseFilePath()
|
||||
{
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Filters = new List<FileDialogFilter>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Extensions = new List<string>{"html"},
|
||||
Name = "HTML files"
|
||||
}
|
||||
},
|
||||
InitialFileName = Path.GetFileName(SlicerFile.FileFullPath) + ".html",
|
||||
Directory = Path.GetDirectoryName(SlicerFile.FileFullPath)
|
||||
};
|
||||
var file = await dialog.ShowAsync(ParentWindow);
|
||||
if (string.IsNullOrWhiteSpace(file)) return;
|
||||
Operation.FilePath = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,7 @@ public partial class MainWindow : WindowEx
|
||||
new() { Tag = new OperationLayerRemove()},
|
||||
new() { Tag = new OperationLayerExportImage()},
|
||||
new() { Tag = new OperationLayerExportGif()},
|
||||
new() { Tag = new OperationLayerExportHtml()},
|
||||
new() { Tag = new OperationLayerExportSkeleton()},
|
||||
new() { Tag = new OperationLayerExportHeatMap()},
|
||||
new() { Tag = new OperationLayerExportMesh()},
|
||||
|
||||
@@ -52,6 +52,7 @@ public class OperationProfiles //: IList<Operation>
|
||||
[XmlElement(typeof(OperationScripting))]
|
||||
|
||||
[XmlElement(typeof(OperationLayerExportGif))]
|
||||
[XmlElement(typeof(OperationLayerExportHtml))]
|
||||
|
||||
[XmlElement(typeof(OperationCalibrateExposureFinder))]
|
||||
[XmlElement(typeof(OperationCalibrateElephantFoot))]
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<Version>3.5.2</Version>
|
||||
<Version>3.5.3</Version>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<PackageIcon>UVtools.png</PackageIcon>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
@@ -44,9 +44,9 @@
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.15" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="2.0.1" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia" Version="5.0.2" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="5.0.2" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="5.0.2" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia" Version="5.1.0" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="5.1.0" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="5.1.0" />
|
||||
<PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.14" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
#
|
||||
# https://gist.github.com/lantrix/738ebfa616d5222a8b1db947793bc3fc
|
||||
#
|
||||
if($PSVersionTable.PSVersion.Major -lt 7){
|
||||
Write-Error("Powershell version $($PSVersionTable.PSVersion) is not compatible with this build script.`n
|
||||
You need at least the version 7.")
|
||||
return;
|
||||
}
|
||||
|
||||
####################################
|
||||
### Fix Zip slash ###
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user