poly-mech/cad/drawers/tools/sw/box/Program.cs
2025-07-04 18:21:52 +02:00

151 lines
6.8 KiB
C#

using System;
using System.Runtime.InteropServices;
using CommandLine;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
namespace SolidWorksBoxGenerator
{
// Class to hold the parsed command-line options
public class Options
{
[Option('o', "output", Required = true, HelpText = "Absolute path for the output .SLDPRT file.")]
public string OutputFile { get; set; }
[Option('w', "width", Default = 500.0, HelpText = "Total width of the box.")]
public double Width { get; set; }
[Option('l', "length", Default = 500.0, HelpText = "Total length of the box.")]
public double Length { get; set; }
[Option('h', "height", Default = 80.0, HelpText = "Height of the box walls.")]
public double Height { get; set; }
[Option('t', "thickness", Default = 3.0, HelpText = "Sheet metal thickness.")]
public double Thickness { get; set; }
[Option('r', "radius", Default = 1.0, HelpText = "Bend radius for sheet metal.")]
public double Radius { get; set; }
}
class Program
{
static void Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args)
.WithParsed<Options>(o =>
{
try
{
Console.WriteLine("Attempting to connect to SolidWorks...");
SldWorks swApp = GetSldWorks();
if (swApp == null)
{
Console.WriteLine("Could not connect to SolidWorks. Please ensure it is running.");
return;
}
Console.WriteLine("Successfully connected to SolidWorks.");
GenerateBox(swApp, o);
}
catch (Exception e)
{
Console.WriteLine($"An error occurred: {e.Message}");
Console.WriteLine(e.StackTrace);
}
});
}
private static SldWorks GetSldWorks()
{
// Connect to a running instance of SolidWorks
try
{
return (SldWorks)Marshal.GetActiveObject("SldWorks.Application");
}
catch (COMException)
{
return null;
}
}
private static void GenerateBox(SldWorks swApp, Options opts)
{
// Convert all measurements from mm to meters for SolidWorks
double width = opts.Width / 1000.0;
double length = opts.Length / 1000.0;
double height = opts.Height / 1000.0;
double thickness = opts.Thickness / 1000.0;
double radius = opts.Radius / 1000.0;
// --- Step 1: Create a New Part Document ---
Console.WriteLine("Creating new part document...");
ModelDoc2 swModel = (ModelDoc2)swApp.NewPart();
if (swModel == null)
{
Console.WriteLine("Failed to create new part.");
return;
}
FeatureManager featMan = swModel.FeatureManager;
SketchManager skMan = swModel.SketchManager;
swModel.ClearSelection2(true);
// --- Step 2: Create the Base Flange ---
Console.WriteLine("Creating base flange...");
// Select the Top Plane (defined as "Plane3" internally by the API)
swModel.Extension.SelectByID2("Plane3", "PLANE", 0, 0, 0, false, 0, null, 0);
skMan.InsertSketch(true);
skMan.CreateCenterRectangle(0, 0, 0, width / 2, length / 2, 0);
skMan.InsertSketch(true);
Feature sheetMetalFeature = featMan.InsertSheetMetalBaseFlange2(thickness, false, radius, 0, 0, 0, 0.5, 0, 0, 0, false, false, false, false);
if(sheetMetalFeature == null)
{
Console.WriteLine("Failed to create base flange.");
swApp.CloseDoc(swModel.GetTitle());
return;
}
swModel.ClearSelection2(true);
// --- Step 3: Create Edge Flanges (Walls) ---
Console.WriteLine("Creating edge flanges for walls...");
object[] edges = new object[4];
edges[0] = GetEdgeByVertex(swModel, width / 2, length / 2, 0); // Front-Right edge
edges[1] = GetEdgeByVertex(swModel, -width / 2, length / 2, 0); // Front-Left edge
edges[2] = GetEdgeByVertex(swModel, -width / 2, -length / 2, 0); // Back-Left edge
edges[3] = GetEdgeByVertex(swModel, width / 2, -length / 2, 0); // Back-Right edge
// Selecting all 4 edges at once to create mitered corners automatically
swModel.Extension.SelectByID2(((IEntity)edges[0]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
swModel.Extension.SelectByID2(((IEntity)edges[1]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
swModel.Extension.SelectByID2(((IEntity)edges[2]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
swModel.Extension.SelectByID2(((IEntity)edges[3]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
featMan.InsertSheetMetalEdgeFlange(height, radius, (90.0 * Math.PI / 180.0), (int)swSheetMetalFlangeLengthMethod_e.swSheetMetalFlangeLengthMethod_OuterVirtualSharp, 0, (int)swSheetMetalFlangePosition_e.swSheetMetalFlangePosition_MaterialInside, false, 0, 0, 0, 0, false, false);
swModel.ClearSelection2(true);
// --- Step 4: Save and Close ---
Console.WriteLine($"Saving file to {opts.OutputFile}...");
bool saveSuccess = swModel.Extension.SaveAs(opts.OutputFile, (int)swSaveAsVersion_e.swSaveAsCurrentVersion, (int)swSaveAsOptions_e.swSaveAsOptions_Silent, null, 0, 0);
if (saveSuccess)
{
Console.WriteLine("File saved successfully.");
}
else
{
Console.WriteLine("Failed to save the file.");
}
swApp.CloseDoc(swModel.GetTitle());
}
// Helper function to find an edge based on one of its vertices' coordinates
private static IEdge GetEdgeByVertex(ModelDoc2 model, double x, double y, double z)
{
var body = ((PartDoc)model).GetBodies2((int)swBodyType_e.swSolidBody, true)[0] as IBody2;
var vertex = body.GetFinniestVertex(x,y,z) as IVertex;
return vertex.GetEdges()[0] as IEdge;
}
}
}