SOLIDWORKS C# API - Create Line Code Refactor
Objective
I want to:
- Refactor
CreateLineMethod
function for unit testing compatible. - Add unit test cases into our solution to make our code testable.
- We will continue from previous article 🚀 Create Line.
- I will not explain each line, since they are already explained in previous articles.
Demo Video
Watch the video below to learn how to refactor the CreateLineMethod
function.
Please note that there are no explanation in the video.
Explanation of each step and why we write code this way is given in this post.
Code Overview and Summary
The code comprises several functions working together to create a sketch line. Each function has a specific responsibility:
- Create
Interface
and register them. CreateLineMethod
acts as the entry point, coordinating other functions.CreateSolidworksInstance
ensures SolidWorks is running and prepares the application.CreatePartDocument
creates a new part document in SolidWorks.SelectSketchPlane
selects a plane for sketching.ApplyUnitConversion
converts points using the correct length units.CreateLine
draws the line based on the converted points.
Below is a detailed breakdown of each function.
Create Interface
- First we need to create a folder in our solution.
- Name of folder:
Interface
- Inside this folder create 2
Interface
IPointViewModel
IUnitConversionHelper
IPointViewModel
code as shown below.
namespace SolidworksTest.Interfaces;
public interface IPointViewModel
{
string Header { get; set; }
double XPoint { get; set; }
double YPoint { get; set; }
double ZPoint { get; set; }
}
IUnitConversionHelper
code as shown below.
using SwConst;
namespace SolidworksTest.Interfaces;
public interface IUnitConversionHelper
{
double AngleConversionFactor { get; set; }
double LengthConversionFactor { get; set; }
void UnitConversion(swLengthUnit_e swUnit);
}
Register Interface
- Open
App.xaml.cs
as shown below:
- Update
RegisterTypes
function as shown below.
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IPointViewModel,PointViewModel>();
containerRegistry.Register<IUnitConversionHelper, UnitConversionHelper>();
}
- In above code, we register
IPointViewModel
into DI container. - When we asked to create object for
IPointViewModel
interface, it will createPointViewModel
type object. - Same goes for
IUnitConversionHelper
interface. - If we asked to create object for
IUnitConversionHelper
interface, it will createUnitConversionHelper
type object.
Update MainWindowViewModel
In MainWindowViewModel, we need to update 2 things:
- Properties
- Constructor Parameters
- Private Fields
Properties Update
- Now we need to update
MainWindowViewModel
. - Update type of
StartPointViewModel
andEndPointViewModel
properties.- Old Type:
PointViewModel
- New Type:
IPointViewModel
- Old Type:
- Update the code as shown below.
private IPointViewModel _startPointViewModel;
public IPointViewModel StartPointViewModel
{
get { return _startPointViewModel; }
set { SetProperty(ref _startPointViewModel, value); }
}
private IPointViewModel _endpointViewModel;
public IPointViewModel EndPointViewModel
{
get { return _endpointViewModel; }
set { SetProperty(ref _endpointViewModel, value); }
}
-
Now in
MainWindowViewModel
constructor, we need to create object for these properties using DI. -
Please see below code for reference.
public MainWindowViewModel(IEventAggregator eventAggregator, IContainerProvider container)
{
this.eventAggregator = eventAggregator;
this.container = container;
StartPointViewModel = this.container.Resolve<IPointViewModel>();
EndPointViewModel = this.container.Resolve<IPointViewModel>();
}
In above code, below lines are responsibile for create objects for StartPointViewModel
and EndPointViewModel
properties.
StartPointViewModel = this.container.Resolve<IPointViewModel>();
EndPointViewModel = this.container.Resolve<IPointViewModel>();
Constructor Parameters Update
- We need additional parameter in our MainWindowViewModel Constructor and assign it to a private field.
- Additiona Parameter: IUnitConversionHelper
- Please see below code for reference.
public IUnitConversionHelper conversionHelper;
public MainWindowViewModel(IEventAggregator eventAggregator, IContainerProvider container, IUnitConversionHelper conversionHelper)
{
this.eventAggregator = eventAggregator;
this.container = container;
StartPointViewModel = this.container.Resolve<IPointViewModel>();
EndPointViewModel = this.container.Resolve<IPointViewModel>();
this.conversionHelper = conversionHelper;
}
In above code, please note following.
- Input Parameter:
IUnitConversionHelper conversionHelper
- Private Field:
this.conversionHelper
Private Fields Update
- Now we need to remove some private fields.
- Those fields are listed below.
private SldWorks.SldWorks swApp;
private ModelDoc2 swDoc;
- These variables we will use create directly in our functions.
Update Method - CreateLineMethod
- Now we need to update
CreateLineMethod()
method as shown below.
public bool CreateLineMethod()
{
ModelDoc2 swDoc;
if (CreateSolidworksInstance(out swDoc) == false)
return false;
swDoc.ClearSelection2(true);
swDoc.ViewZoomtofit2();
messageToShow = "Sketch line successfully created.";
return true;
}
Purpose
CreateLineMethod()
method’s purpose is to create a line in a SolidWorks document.- While the code for drawing the line isn’t shown.
- It prepares a SolidWorks instance, clears any selections, and adjusts the view.
Return Type
- The
CreateLineMethod()
method returns abool
(Boolean value) —true
orfalse
. - This return type usually indicates success (
true
) or failure (false
) of the method.
Flow/Summary
- Calls
CreateSolidworksInstance
to start SolidWorks and prepare a document. - Clears any current selections in the document.
- Zooms the view to fit the entire sketch.
- Sets a success message if no errors occur and returns
true
. - Please see below 👇🏻 flow digram to understand the functions.
Create Method - CreateSolidworksInstance
- Now we need to create
CreateSolidworksInstance()
method as shown below.
public virtual bool CreateSolidworksInstance(out ModelDoc2 swDoc)
{
SldWorks.SldWorks swApp = new SldWorks.SldWorks();
if (swApp == null)
{
messageToShow = "Failed to find Solidworks application.";
swDoc = null;
return false;
}
swApp.Visible = true;
return CreatePartDocument(swApp,out swDoc);
}
Purpose
CreateSolidworksInstance()
method’s purpose is to:- create an instance of SolidWorks.
- make it visible
- then attempt to create a part document in SolidWorks
Return Type
- The
CreateSolidworksInstance()
method returns abool
(Boolean value) —true
orfalse
. - This return type usually indicates success (
true
) or failure (false
) of the method.
Flow/Summary
- Tries to create an instance of SolidWorks.
- If SolidWorks cannot be found, sets an error message and returns
false
. - Makes the SolidWorks application visible to the user.
- Calls
CreatePartDocument
to create a new part document and returns its result. - Please see below 👇🏻 flow digram to understand the functions.
Create Method - CreatePartDocument
- Now we need to create
CreatePartDocument()
method as shown below.
public bool CreatePartDocument(SldWorks.SldWorks swApp,out ModelDoc2 swDoc)
{
string defaultTemplate = swApp.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplatePart);
if (string.IsNullOrEmpty(defaultTemplate))
{
messageToShow = "Default part template is empty.";
swDoc = null;
return false;
}
swDoc = swApp.NewDocument(defaultTemplate, 0, 0, 0);
if (swDoc == null)
{
messageToShow = "Failed to create new Part document.";
return false;
}
return SelectSketchPlane(swApp, swDoc);
}
Purpose
CreatePartDocument()
method’s purpose is to:- create a new part document in SolidWorks using a default template.
- sets up a sketch plane for further operations.
Return Type
- The
CreatePartDocument()
method returns abool
(Boolean value) —true
orfalse
. - This return type usually indicates success (
true
) or failure (false
) of the method.
Flow/Summary
- Fetches the default part template from SolidWorks user preferences.
- Checks if the template is valid. If not, sets an error message and returns
false
. - Creates a new part document using the template.
- Calls
SelectSketchPlane
to set up a plane for sketching and returns its result. - Please see below 👇🏻 flow digram to understand the functions.
Create Method - SelectSketchPlane
- Now we need to create
SelectSketchPlane()
method as shown below.
public bool SelectSketchPlane(SldWorks.SldWorks swApp, ModelDoc2 swDoc)
{
bool boolStatus = swDoc.Extension.SelectByID2("Right Plane", "PLANE", 0, 0, 0, false, 0, null, (int)swSelectOption_e.swSelectOptionDefault);
if (boolStatus == false)
{
messageToShow = "Failed to select Right Plane";
swApp.CloseAllDocuments(true);
swApp.ExitApp();
return false;
}
swDoc.SketchManager.InsertSketch(false);
double x1, y1, z1, x2, y2, z2;
var lengthUnit = swDoc.LengthUnit;
conversionHelper.UnitConversion((swLengthUnit_e)lengthUnit);
(x1, y1, z1) = ApplyUnitConversion(StartPointViewModel, conversionHelper.LengthConversionFactor);
(x2, y2, z2) = ApplyUnitConversion(EndPointViewModel, conversionHelper.LengthConversionFactor);
SketchSegment sketchSegment = null;
return CreateLine(sketchSegment, x1, y1, z1, swApp, swDoc.SketchManager, x2, y2, z2);
}
Purpose
SelectSketchPlane()
method’s purpose is to:- select a specific sketch plane (e.g., the Right Plane) in the SolidWorks part document.
- then insert a new sketch.
Return Type
- The
SelectSketchPlane()
method returns abool
(Boolean value) —true
orfalse
. - This return type usually indicates success (
true
) or failure (false
) of the method.
Flow/Summary
- Attempts to select the Right Plane in the part document.
- If the selection fails, closes all documents, exits SolidWorks, and sets an error message.
- Inserts a new sketch on the selected plane.
- Converts the provided points using
ApplyUnitConversion
and passes them toCreateLine
. - Please see below 👇🏻 flow digram to understand the functions.
Create Method - ApplyUnitConversion
- Now we need to create
ApplyUnitConversion()
method as shown below.
public (double, double, double) ApplyUnitConversion(IPointViewModel inputPoint, double lengthConversionFactor)
{
double X, Y, Z;
X = inputPoint.XPoint * lengthConversionFactor;
Y = inputPoint.YPoint * lengthConversionFactor;
Z = inputPoint.ZPoint * lengthConversionFactor;
return (X, Y, Z);
}
Purpose
ApplyUnitConversion()
method’s purpose is to:- convert a point’s coordinates (X, Y, Z) based on the length units set in the SolidWorks document.
Return Type
- The
ApplyUnitConversion()
method returns(double, double, double)
. - This returnS the converted X, Y, and Z coordinates as a
tuple
.
Flow/Summary
- Takes an input point and the length conversion factor.
- Multiplies each coordinate
(X, Y, Z)
of the input point by the conversion factor. - Returns the converted coordinates as a
tuple
. - Please see below 👇🏻 flow digram to understand the functions.
Create Method - CreateLine
- Now we need to create
CreateLine()
method as shown below.
public bool CreateLine(SketchSegment sketchSegment, double x1, double y1, double z1, SldWorks.SldWorks swApp, SketchManager swSketchManager, double x2, double y2, double z2)
{
sketchSegment = swSketchManager.CreateLine(x1, y1, z1, x2, y2, z2);
if (sketchSegment == null)
{
messageToShow = "Failed to Create Sketch line.";
swApp.CloseAllDocuments(true);
swApp.ExitApp();
return false;
}
return true;
}
Purpose
CreateLine()
method’s purpose is:- To draw a sketch line in the SolidWorks part document using the provided start and end points.
Return Type
- The
CreateLine()
method returns abool
(Boolean value) —true
orfalse
. - This return type usually indicates success (
true
) or failure (false
) of the method.
Flow/Summary
- Uses the SolidWorks
SketchManager.CreateLine
method to draw a line between start and end points. - If the line creation
fails
, sets an error message, closes all documents, and exits SolidWorks. - Returns
true
if the line is successfully created. - Please see below 👇🏻 flow digram to understand the functions.
This is it !!!
I hope my efforts will helpful to someone!
If you found anything to add or update, please let me know on my e-mail.
Hope this post helps you to Understand Refactor Code.
If you like the post then please share it with your friends also.
Do let me know by you like this post or not!
Till then, Happy learning!!!