From c9a8442a294534fab89ecd40214150963b0c790d Mon Sep 17 00:00:00 2001 From: AJ Date: Wed, 1 Oct 2025 09:44:07 -0400 Subject: [PATCH] Refactored ExportContext --- ExportDXF/ExportDXF.csproj | 14 +- ExportDXF/Models/ExportContext.cs | 92 +++++++++++++ ExportDXF/Services/DrawingExporter.cs | 52 +++++-- ExportDXF/Services/DxfExportService.cs | 181 ++++++++++--------------- ExportDXF/Services/PartExporter.cs | 59 ++++---- 5 files changed, 244 insertions(+), 154 deletions(-) diff --git a/ExportDXF/ExportDXF.csproj b/ExportDXF/ExportDXF.csproj index b1251a3..e617553 100644 --- a/ExportDXF/ExportDXF.csproj +++ b/ExportDXF/ExportDXF.csproj @@ -26,7 +26,7 @@ Rogers Engineering true publish.htm - 6 + 7 1.6.0.%2a false true @@ -99,6 +99,12 @@ + + Form + + + MainForm.cs + @@ -122,12 +128,6 @@ - - Form - - - MainForm.cs - diff --git a/ExportDXF/Models/ExportContext.cs b/ExportDXF/Models/ExportContext.cs index 9b5bec9..fb4dae7 100644 --- a/ExportDXF/Models/ExportContext.cs +++ b/ExportDXF/Models/ExportContext.cs @@ -1,7 +1,11 @@ using ExportDXF.ViewFlipDeciders; +using SolidWorks.Interop.sldworks; +using SolidWorks.Interop.swconst; using System; using System.Drawing; +using System.IO; using System.Threading; +using System.Windows.Forms; namespace ExportDXF.Services { @@ -10,6 +14,9 @@ namespace ExportDXF.Services /// public class ExportContext { + private const string DRAWING_TEMPLATE_FOLDER = "Templates"; + private const string DRAWING_TEMPLATE_FILE = "Blank.drwdot"; + /// /// The document to be exported. /// @@ -34,5 +41,90 @@ namespace ExportDXF.Services /// Callback for reporting progress and status messages. /// public Action ProgressCallback { get; set; } + + public void LogProgress(string message, Color? color = null) + { + ProgressCallback?.Invoke(message, color); + } + + public SldWorks SolidWorksApp { get; set; } + + public DrawingDoc TemplateDrawing { get; set; } + + private string DrawingTemplatePath + { + get + { + return Path.Combine( + Application.StartupPath, + DRAWING_TEMPLATE_FOLDER, + DRAWING_TEMPLATE_FILE); + } + } + + public DrawingDoc GetOrCreateTemplateDrawing() + { + if (TemplateDrawing != null) + return TemplateDrawing; + + TemplateDrawing = SolidWorksApp.NewDocument( + DrawingTemplatePath, + (int)swDwgPaperSizes_e.swDwgPaperDsize, + 1, + 1) as DrawingDoc; + + return TemplateDrawing; + } + + public void CleanupTemplateDrawing() + { + try + { + if (TemplateDrawing == null) + return; + + if (SolidWorksApp == null) + { + ProgressCallback?.Invoke("Warning: Cannot cleanup template drawing - SolidWorks app not available", Color.DarkBlue); + TemplateDrawing = null; + return; + } + + var model = TemplateDrawing as ModelDoc2; + if (model != null) + { + var title = model.GetTitle(); + + if (!string.IsNullOrEmpty(title)) + { + // Close the document without saving + SolidWorksApp.CloseDoc(title); + ProgressCallback?.Invoke("Closed template drawing", null); + } + } + + // Clear the reference regardless of success/failure + TemplateDrawing = null; + } + catch (Exception ex) + { + ProgressCallback?.Invoke($"Failed to close template drawing: {ex.Message}", Color.Red); + + // Still clear the reference to prevent further issues + TemplateDrawing = null; + + // Don't throw here as this is cleanup code - log the error but continue + } + } + + public void CloseDocument(string title) + { + SolidWorksApp?.CloseDoc(title); + } + + public ModelDoc2 CreateDocument(string templatePath, int paperSize, double width, double height) + { + return SolidWorksApp?.NewDocument(templatePath, paperSize, width, height) as ModelDoc2; + } } } \ No newline at end of file diff --git a/ExportDXF/Services/DrawingExporter.cs b/ExportDXF/Services/DrawingExporter.cs index 961f0a6..bd3aed6 100644 --- a/ExportDXF/Services/DrawingExporter.cs +++ b/ExportDXF/Services/DrawingExporter.cs @@ -16,14 +16,13 @@ namespace ExportDXF.Services /// /// The drawing document to export. /// The directory where the PDF file will be saved. - /// Optional callback for progress updates. - void ExportToPdf(DrawingDoc drawing, string saveDirectory, Action progressCallback); + /// The export context containing SolidWorks app and callbacks. + void ExportToPdf(DrawingDoc drawing, string saveDirectory, ExportContext context); } - public class DrawingExporter : IDrawingExporter { - public void ExportToPdf(DrawingDoc drawing, string saveDirectory, Action progressCallback) + public void ExportToPdf(DrawingDoc drawing, string saveDirectory, ExportContext context) { if (drawing == null) throw new ArgumentNullException(nameof(drawing)); @@ -31,27 +30,40 @@ namespace ExportDXF.Services if (string.IsNullOrWhiteSpace(saveDirectory)) throw new ArgumentException("Save directory cannot be null or empty.", nameof(saveDirectory)); + if (context == null) + throw new ArgumentNullException(nameof(context)); + + if (context.SolidWorksApp == null) + throw new ArgumentException("SolidWorksApp cannot be null in context.", nameof(context)); + try { var pdfFileName = GetPdfFileName(drawing); var pdfPath = Path.Combine(saveDirectory, pdfFileName); var model = drawing as ModelDoc2; - var sldWorks = (SldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")); + var sldWorks = context.SolidWorksApp; var exportData = sldWorks.GetExportFileData( (int)swExportDataFileType_e.swExportPdfData) as ExportPdfData; + if (exportData == null) + { + throw new InvalidOperationException("Failed to get PDF export data from SolidWorks."); + } + exportData.ViewPdfAfterSaving = false; exportData.SetSheets( (int)swExportDataSheetsToExport_e.swExportData_ExportAllSheets, drawing); + context.ProgressCallback?.Invoke($"Exporting drawing to PDF: \"{pdfFileName}\"", null); + int errors = 0; int warnings = 0; var modelExtension = model.Extension; - modelExtension.SaveAs( + var success = modelExtension.SaveAs( pdfPath, (int)swSaveAsVersion_e.swSaveAsCurrentVersion, (int)swSaveAsOptions_e.swSaveAsOptions_Silent, @@ -59,19 +71,29 @@ namespace ExportDXF.Services ref errors, ref warnings); - if (errors == 0) + if (success && errors == 0) { - progressCallback?.Invoke($"Saved drawing to PDF: \"{pdfFileName}\"", Color.Green); + context.ProgressCallback?.Invoke($"Saved drawing to PDF: \"{pdfFileName}\"", Color.Green); + } + else if (success && warnings > 0) + { + context.ProgressCallback?.Invoke( + $"PDF export completed with warnings: {warnings}", + Color.DarkBlue); } else { - progressCallback?.Invoke($"PDF export completed with errors: {errors}", Color.Yellow); + context.ProgressCallback?.Invoke( + $"PDF export failed. Errors: {errors}, Warnings: {warnings}", + Color.Red); + throw new InvalidOperationException($"PDF export failed with {errors} errors and {warnings} warnings."); } } catch (Exception ex) { - progressCallback?.Invoke($"Failed to export PDF: {ex.Message}", Color.Red); - throw; + var errorMessage = $"Failed to export PDF: {ex.Message}"; + context.ProgressCallback?.Invoke(errorMessage, Color.Red); + throw new InvalidOperationException(errorMessage, ex); } } @@ -79,6 +101,14 @@ namespace ExportDXF.Services { var model = drawing as ModelDoc2; var modelFilePath = model.GetPathName(); + + if (string.IsNullOrEmpty(modelFilePath)) + { + // Handle unsaved documents + var title = model.GetTitle(); + return string.IsNullOrEmpty(title) ? "Untitled.pdf" : Path.GetFileNameWithoutExtension(title) + ".pdf"; + } + return Path.GetFileNameWithoutExtension(modelFilePath) + ".pdf"; } } diff --git a/ExportDXF/Services/DxfExportService.cs b/ExportDXF/Services/DxfExportService.cs index 83939de..b89786f 100644 --- a/ExportDXF/Services/DxfExportService.cs +++ b/ExportDXF/Services/DxfExportService.cs @@ -25,9 +25,6 @@ namespace ExportDXF.Services /// public class DxfExportService : IDxfExportService { - private const string DRAWING_TEMPLATE_FOLDER = "Templates"; - private const string DRAWING_TEMPLATE_FILE = "Blank.drwdot"; - private readonly ISolidWorksService _solidWorksService; private readonly IBomExtractor _bomExtractor; private readonly IPartExporter _partExporter; @@ -57,6 +54,7 @@ namespace ExportDXF.Services throw new ArgumentNullException(nameof(context)); ValidateContext(context); + SetupExportContext(context); var startTime = DateTime.Now; @@ -85,6 +83,7 @@ namespace ExportDXF.Services } finally { + CleanupExportContext(context); _solidWorksService.EnableUserControl(true); var duration = DateTime.Now - startTime; @@ -131,7 +130,7 @@ namespace ExportDXF.Services if (items == null || items.Count == 0) { - LogProgress(context, "No items found in assembly.", Color.Yellow); + LogProgress(context, "No items found in assembly.", Color.DarkBlue); return; } @@ -177,7 +176,7 @@ namespace ExportDXF.Services } // Export drawing to PDF first - _drawingExporter.ExportToPdf(drawing, saveDirectory, context.ProgressCallback); + _drawingExporter.ExportToPdf(drawing, saveDirectory, context); // Then export parts to DXF ExportItems(items, saveDirectory, context); @@ -185,6 +184,40 @@ namespace ExportDXF.Services #endregion + #region Context Management + + private void SetupExportContext(ExportContext context) + { + // Set up SolidWorks application reference + context.SolidWorksApp = _solidWorksService.GetNativeSldWorks(); + + if (context.SolidWorksApp == null) + { + throw new InvalidOperationException("SolidWorks service is not connected."); + } + + // Set up drawing template path + context.TemplateDrawing = null; + + LogProgress(context, "Export context initialized", null); + } + + private void CleanupExportContext(ExportContext context) + { + try + { + // Clean up template drawing if it was created + context.CleanupTemplateDrawing(); + } + catch (Exception ex) + { + LogProgress(context, $"Warning: Failed to cleanup template drawing: {ex.Message}", Color.DarkBlue); + // Don't throw - this is cleanup code + } + } + + #endregion + #region Item Processing private List ExtractItemsFromAssembly(AssemblyDoc assembly, ExportContext context) @@ -207,117 +240,43 @@ namespace ExportDXF.Services private void ExportItems(List items, string saveDirectory, ExportContext context) { - DrawingDoc templateDrawing = null; + LogProgress(context, "", null); - try + int successCount = 0; + int failureCount = 0; + + foreach (var item in items) { - templateDrawing = CreateTemplateDrawing(); + if (context.CancellationToken.IsCancellationRequested) + { + LogProgress(context, "Export canceled by user.", Color.DarkBlue); + return; + } + + try + { + // PartExporter will handle template drawing creation through context + _partExporter.ExportItem(item, saveDirectory, context); + + if (!string.IsNullOrEmpty(item.FileName)) + successCount++; + else + failureCount++; + } + catch (Exception ex) + { + LogProgress(context, $"Error exporting item {item.ItemNo}: {ex.Message}", Color.Red); + failureCount++; + } LogProgress(context, "", null); - - int successCount = 0; - int failureCount = 0; - - foreach (var item in items) - { - if (context.CancellationToken.IsCancellationRequested) - { - LogProgress(context, "Export canceled by user.", Color.Yellow); - return; - } - - try - { - _partExporter.ExportItem(item, templateDrawing, saveDirectory, context); - - if (!string.IsNullOrEmpty(item.FileName)) - successCount++; - else - failureCount++; - } - catch (Exception ex) - { - LogProgress(context, $"Error exporting item {item.ItemNo}: {ex.Message}", Color.Red); - failureCount++; - } - - LogProgress(context, "", null); - } - - LogProgress(context, $"Export complete: {successCount} succeeded, {failureCount} failed", - failureCount > 0 ? Color.Yellow : Color.Green); - - // Create BOM Excel file - CreateBomExcelFile(items, saveDirectory, context); - } - finally - { - CloseTemplateDrawing(templateDrawing); - } - } - - #endregion - - #region Template Drawing Management - - private DrawingDoc CreateTemplateDrawing() - { - var sldWorks = _solidWorksService.GetNativeSldWorks(); - - if (sldWorks == null) - throw new InvalidOperationException("SolidWorks service is not connected."); - - var templatePath = GetDrawingTemplatePath(); - - if (!File.Exists(templatePath)) - { - throw new FileNotFoundException( - $"Drawing template not found at: {templatePath}", - templatePath); } - var drawing = sldWorks.NewDocument( - templatePath, - (int)swDwgPaperSizes_e.swDwgPaperDsize, - 1, - 1) as DrawingDoc; + LogProgress(context, $"Export complete: {successCount} succeeded, {failureCount} failed", + failureCount > 0 ? Color.DarkBlue : Color.Green); - if (drawing == null) - { - throw new InvalidOperationException( - "Failed to create drawing from template. Please check the template file."); - } - - return drawing; - } - - private void CloseTemplateDrawing(DrawingDoc drawing) - { - if (drawing == null) - return; - - try - { - var model = drawing as ModelDoc2; - var title = model?.GetTitle(); - - if (!string.IsNullOrEmpty(title)) - { - _solidWorksService.CloseDocument(title); - } - } - catch - { - // Ignore errors during cleanup - } - } - - private string GetDrawingTemplatePath() - { - return Path.Combine( - Application.StartupPath, - DRAWING_TEMPLATE_FOLDER, - DRAWING_TEMPLATE_FILE); + // Create BOM Excel file + CreateBomExcelFile(items, saveDirectory, context); } #endregion @@ -408,6 +367,8 @@ namespace ExportDXF.Services context.ProgressCallback?.Invoke(message, color); } + + #endregion } -} +} \ No newline at end of file diff --git a/ExportDXF/Services/PartExporter.cs b/ExportDXF/Services/PartExporter.cs index 507bcff..17993ef 100644 --- a/ExportDXF/Services/PartExporter.cs +++ b/ExportDXF/Services/PartExporter.cs @@ -25,10 +25,9 @@ namespace ExportDXF.Services /// Exports an item (component from BOM or assembly) to DXF. /// /// The item to export. - /// The template drawing to use for creating flat patterns. /// The directory where the DXF file will be saved. /// The export context. - void ExportItem(Item item, DrawingDoc templateDrawing, string saveDirectory, ExportContext context); + void ExportItem(Item item, string saveDirectory, ExportContext context); } public class PartExporter : IPartExporter @@ -38,6 +37,12 @@ namespace ExportDXF.Services if (part == null) throw new ArgumentNullException(nameof(part)); + if (string.IsNullOrWhiteSpace(saveDirectory)) + throw new ArgumentException("Save directory cannot be null or empty.", nameof(saveDirectory)); + + if (context == null) + throw new ArgumentNullException(nameof(context)); + var model = part as ModelDoc2; var activeConfig = model.GetActiveConfiguration() as SolidWorks.Interop.sldworks.Configuration; var originalConfigName = activeConfig?.Name; @@ -47,16 +52,9 @@ namespace ExportDXF.Services var fileName = GetSinglePartFileName(model, context.FilePrefix); var savePath = Path.Combine(saveDirectory, fileName + ".dxf"); - var templateDrawing = CreateTemplateDrawing(context); + context.GetOrCreateTemplateDrawing(); - try - { - ExportPartToDxf(part, originalConfigName, templateDrawing, savePath, context); - } - finally - { - CloseTemplateDrawing(templateDrawing, context); - } + ExportPartToDxf(part, originalConfigName, savePath, context); } finally { @@ -67,8 +65,14 @@ namespace ExportDXF.Services } } - public void ExportItem(Item item, DrawingDoc templateDrawing, string saveDirectory, ExportContext context) + public void ExportItem(Item item, string saveDirectory, ExportContext context) { + if (string.IsNullOrWhiteSpace(saveDirectory)) + throw new ArgumentException("Save directory cannot be null or empty.", nameof(saveDirectory)); + + if (context == null) + throw new ArgumentNullException(nameof(context)); + if (item?.Component == null) { context.ProgressCallback?.Invoke($"Item {item?.ItemNo} - skipped, no component", Color.Yellow); @@ -93,7 +97,9 @@ namespace ExportDXF.Services var fileName = GetItemFileName(item, context.FilePrefix); var savePath = Path.Combine(saveDirectory, fileName + ".dxf"); - if (ExportPartToDxf(part, item.Component.ReferencedConfiguration, templateDrawing, savePath, context)) + var templateDrawing = context.GetOrCreateTemplateDrawing(); + + if (ExportPartToDxf(part, item.Component.ReferencedConfiguration, savePath, context)) { item.FileName = Path.GetFileNameWithoutExtension(savePath); } @@ -116,8 +122,18 @@ namespace ExportDXF.Services // Get description from custom properties var config = item.Component.ReferencedConfiguration; - item.Description = model.Extension.CustomPropertyManager[config].Get("Description"); - item.Description = model.Extension.CustomPropertyManager[""].Get("Description"); + + // Try configuration-specific properties first + var configPropertyManager = model.Extension.CustomPropertyManager[config]; + item.Description = configPropertyManager?.Get("Description"); + + // Fall back to document-level properties if no config-specific description + if (string.IsNullOrEmpty(item.Description)) + { + var docPropertyManager = model.Extension.CustomPropertyManager[""]; + item.Description = docPropertyManager?.Get("Description"); + } + item.Description = TextHelper.RemoveXmlTags(item.Description); // Get material @@ -127,7 +143,6 @@ namespace ExportDXF.Services private bool ExportPartToDxf( PartDoc part, string configName, - DrawingDoc templateDrawing, string savePath, ExportContext context) { @@ -141,6 +156,8 @@ namespace ExportDXF.Services return false; } + var templateDrawing = context.GetOrCreateTemplateDrawing(); + SolidWorksHelper.ConfigureFlatPatternSettings(model); var sheet = templateDrawing.IGetCurrentSheet(); @@ -286,15 +303,5 @@ namespace ExportDXF.Services Color.Red); } } - - private DrawingDoc CreateTemplateDrawing(ExportContext context) - { - throw new NotImplementedException("Template drawing creation not implemented."); - } - - private void CloseTemplateDrawing(DrawingDoc drawing, ExportContext context) - { - throw new NotImplementedException("Template drawing creation not implemented."); - } } } \ No newline at end of file