From 5259548c23cb235e1f06364a31232c414a47c7b9 Mon Sep 17 00:00:00 2001
From: GeKtvi <61162497+GeKtvi@users.noreply.github.com>
Date: Thu, 1 May 2025 21:55:53 +0300
Subject: [PATCH 1/3] Added type safe property access
---
.../Errors/SolidDnaErrorCode.cs | 4 +
.../CustomProperties/CustomPropertyEditor.cs | 136 +++++++++++++++++-
2 files changed, 138 insertions(+), 2 deletions(-)
diff --git a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
index f7e6cf1e..e6a730f1 100644
--- a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
+++ b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
@@ -169,6 +169,10 @@ public enum SolidDnaErrorCode
///
SolidWorksModelGetConfigurationError = 11014,
+ ///
+ ///
+ SolidWorksModelGetPropertyError = 11030,
+
#endregion
#region SolidWorks Command Manager (12,000)
diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
index 71ba0c2b..dc8f59eb 100644
--- a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
+++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
@@ -1,6 +1,8 @@
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
+using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
namespace CADBooster.SolidDna
@@ -10,6 +12,7 @@ namespace CADBooster.SolidDna
///
public class CustomPropertyEditor : SolidDnaObject
{
+ public bool IsTypeCheckEnabled { get; set; } = true;
#region Constructor
///
@@ -45,12 +48,107 @@ public string GetCustomProperty(string name, bool resolve = false)
// TODO: Add error checking and exception catching
// Get custom property
- BaseObject.Get5(name, false, out var val, out var resolvedVal, out var wasResolved);
+ _ = BaseObject.Get5(name, false, out var val, out var resolvedVal, out _);
// Return desired result
return resolve ? resolvedVal : val;
}
+ public string GetStringCustomProperty(string name, bool resolve = false)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoText, true);
+
+ _ = BaseObject.Get5(name, false, out var val, out var resolvedVal, out _);
+
+ return resolve ? resolvedVal : val;
+ }
+
+ public DateTime GetDateCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoDate);
+
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ return DateTime.Parse(resolvedVal);
+ }
+
+ public int GetIntegerCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber);
+
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ return int.Parse(resolvedVal);
+ }
+
+ public double GetDoubleCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber);
+
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ return double.Parse(resolvedVal, CultureInfo.InvariantCulture);
+ }
+
+ public bool GetBooleanCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoYesOrNo);
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ switch (resolvedVal)
+ {
+ case "Yes":
+ return true;
+ case "No":
+ return false;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+
+ public string GetRawEquationCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoEquation, true);
+
+ _ = BaseObject.Get5(name, false, out var val, out _, out _);
+
+ return val;
+ }
+
+ public double GetEvaluatedEquationCustomProperty(string name)
+ {
+ // TODO: Add error checking and exception catching
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoEquation);
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ return double.Parse(resolvedVal, CultureInfo.InvariantCulture);
+ }
+
///
/// Sets the value of a custom property by name
///
@@ -72,9 +170,28 @@ public void SetCustomProperty(string name, string value, swCustomInfoType_e type
//
// Set new one
- BaseObject.Add3(name, (int)type, value, (int)swCustomPropertyAddOption_e.swCustomPropertyReplaceValue);
+ _ = BaseObject.Add3(name, (int)type, value, (int)swCustomPropertyAddOption_e.swCustomPropertyReplaceValue);
}
+ public void SetStringCustomProperty(string name, string value)
+ => SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoText);
+
+ public void SetDateCustomProperty(string name, DateTime value)
+ => SetCustomProperty(name, value.ToString("dd.MM.yyyy"), swCustomInfoType_e.swCustomInfoDate);
+
+ public void SetIntegerCustomProperty(string name, int value)
+ => SetCustomProperty(name, value.ToString(), swCustomInfoType_e.swCustomInfoNumber);
+
+ public void SetDoubleCustomProperty(string name, double value)
+ => SetCustomProperty(name, value.ToString(CultureInfo.InvariantCulture), swCustomInfoType_e.swCustomInfoDouble);
+
+ public void SetBooleanCustomProperty(string name, bool value)
+ => SetCustomProperty(name, value ? "Yes" : "No", swCustomInfoType_e.swCustomInfoYesOrNo);
+
+ public void SetEquationCustomProperty(string name, string value)
+ => SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoEquation);
+
+
///
/// Deletes a custom property by name
///
@@ -107,5 +224,20 @@ public List GetCustomProperties()
// Return the list
return list;
}
+
+ private void ThrowIfExpectedTypeMismatch(string name, swCustomInfoType_e expectedType, bool allowUnknown = false)
+ {
+ var type = (swCustomInfoType_e)BaseObject.GetType2(name);
+
+ if (allowUnknown && type == swCustomInfoType_e.swCustomInfoUnknown)
+ return;
+
+ if (type != expectedType)
+ {
+ throw new SolidDnaException(SolidDnaErrors.CreateError(
+ SolidDnaErrorTypeCode.SolidWorksModel, SolidDnaErrorCode.SolidWorksModelError,
+ $"Property has different type that expected. Received: {type}, expected: {expectedType}"));
+ }
+ }
}
}
From 6d75111a0ef69202115319fb29d8b6c64211fc0e Mon Sep 17 00:00:00 2001
From: GeKtvi <61162497+GeKtvi@users.noreply.github.com>
Date: Thu, 1 May 2025 22:20:52 +0300
Subject: [PATCH 2/3] Added comments about property access
---
.../Errors/SolidDnaErrorCode.cs | 1 +
.../CustomProperties/CustomPropertyEditor.cs | 98 +++++++++++++++++--
2 files changed, 92 insertions(+), 7 deletions(-)
diff --git a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
index e6a730f1..b9ea7657 100644
--- a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
+++ b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
@@ -170,6 +170,7 @@ public enum SolidDnaErrorCode
SolidWorksModelGetConfigurationError = 11014,
///
+ /// Error occurred while trying to get a custom property value from a SolidWorks model
///
SolidWorksModelGetPropertyError = 11030,
diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
index dc8f59eb..a08d6863 100644
--- a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
+++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
@@ -12,6 +12,11 @@ namespace CADBooster.SolidDna
///
public class CustomPropertyEditor : SolidDnaObject
{
+ ///
+ /// Gets or sets whether type checking is enabled when getting property values
+ /// When enabled, methods will verify the property type matches the expected type
+ /// By default is
+ ///
public bool IsTypeCheckEnabled { get; set; } = true;
#region Constructor
@@ -29,7 +34,7 @@ public CustomPropertyEditor(CustomPropertyManager model) : base(model)
/// Checks if a custom property exists
///
/// The name of the custom property
- ///
+ /// If the property exists , otherwise
public bool CustomPropertyExists(string name)
{
// TODO: Add error checking and exception catching
@@ -42,7 +47,7 @@ public bool CustomPropertyExists(string name)
///
/// The name of the custom property
/// True to resolve the custom property value
- ///
+ /// The property value as a string
public string GetCustomProperty(string name, bool resolve = false)
{
// TODO: Add error checking and exception catching
@@ -54,6 +59,13 @@ public string GetCustomProperty(string name, bool resolve = false)
return resolve ? resolvedVal : val;
}
+ ///
+ /// Gets a string value from a custom property
+ ///
+ /// The name of the custom property
+ /// Whether to resolve the value (evaluate equations/formulas)
+ /// The string value of the property
+ /// Thrown if type checking is enabled and the property is not of text type
public string GetStringCustomProperty(string name, bool resolve = false)
{
// TODO: Add error checking and exception catching
@@ -66,6 +78,12 @@ public string GetStringCustomProperty(string name, bool resolve = false)
return resolve ? resolvedVal : val;
}
+ ///
+ /// Gets a DateTime value from a date-type custom property
+ ///
+ /// The name of the custom property
+ /// The parsed DateTime value
+ /// Thrown if type checking is enabled and the property is not of date type
public DateTime GetDateCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -77,8 +95,14 @@ public DateTime GetDateCustomProperty(string name)
_ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
return DateTime.Parse(resolvedVal);
- }
-
+ }
+
+ ///
+ /// Gets an integer value from a number-type custom property
+ ///
+ /// The name of the custom property
+ /// The parsed integer value
+ /// Thrown if type checking is enabled and the property is not of number type
public int GetIntegerCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -90,8 +114,14 @@ public int GetIntegerCustomProperty(string name)
_ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
return int.Parse(resolvedVal);
- }
-
+ }
+
+ ///
+ /// Gets a double value from a number-type custom property
+ ///
+ /// The name of the custom property
+ /// The parsed double value
+ /// Thrown if type checking is enabled and the property is not of number type
public double GetDoubleCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -105,6 +135,12 @@ public double GetDoubleCustomProperty(string name)
return double.Parse(resolvedVal, CultureInfo.InvariantCulture);
}
+ ///
+ /// Gets a boolean value from a yes/no-type custom property
+ ///
+ /// The name of the custom property
+ /// The boolean value ( for "Yes", for "No")
+ /// Thrown if type checking is enabled and the property is not of yes/no type
public bool GetBooleanCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -125,6 +161,12 @@ public bool GetBooleanCustomProperty(string name)
}
}
+ ///
+ /// Gets the raw equation text from an equation-type custom property
+ ///
+ /// The name of the custom property
+ /// The raw equation text
+ /// Thrown if type checking is enabled and the property is not of equation type
public string GetRawEquationCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -137,6 +179,12 @@ public string GetRawEquationCustomProperty(string name)
return val;
}
+ ///
+ /// Gets the evaluated result of an equation-type custom property
+ ///
+ /// The name of the custom property
+ /// The evaluated numeric result
+ /// Thrown if type checking is enabled and the property is not of equation type
public double GetEvaluatedEquationCustomProperty(string name)
{
// TODO: Add error checking and exception catching
@@ -173,25 +221,54 @@ public void SetCustomProperty(string name, string value, swCustomInfoType_e type
_ = BaseObject.Add3(name, (int)type, value, (int)swCustomPropertyAddOption_e.swCustomPropertyReplaceValue);
}
+ ///
+ /// Sets a string value to a text-type custom property
+ ///
+ /// The name of the custom property
+ /// The string value to set
public void SetStringCustomProperty(string name, string value)
=> SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoText);
+ ///
+ /// Sets a date value to a date-type custom property, time data is ignored
+ ///
+ /// The name of the custom property
+ /// The date value to set
public void SetDateCustomProperty(string name, DateTime value)
=> SetCustomProperty(name, value.ToString("dd.MM.yyyy"), swCustomInfoType_e.swCustomInfoDate);
+ ///
+ /// Sets an integer value to a number-type custom property
+ ///
+ /// The name of the custom property
+ /// The integer value to set
public void SetIntegerCustomProperty(string name, int value)
=> SetCustomProperty(name, value.ToString(), swCustomInfoType_e.swCustomInfoNumber);
+ ///
+ /// Sets a double value to a number-type custom property
+ ///
+ /// The name of the custom property
+ /// The double value to set
public void SetDoubleCustomProperty(string name, double value)
=> SetCustomProperty(name, value.ToString(CultureInfo.InvariantCulture), swCustomInfoType_e.swCustomInfoDouble);
+ ///
+ /// Sets a boolean value to a yes/no-type custom property ("Yes" for , "No" for )
+ ///
+ /// The name of the custom property
+ /// The boolean value to set
public void SetBooleanCustomProperty(string name, bool value)
=> SetCustomProperty(name, value ? "Yes" : "No", swCustomInfoType_e.swCustomInfoYesOrNo);
+ ///
+ /// Sets an equation/formula to an equation-type custom property
+ ///
+ /// The name of the custom property
+ /// The equation text to set
public void SetEquationCustomProperty(string name, string value)
=> SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoEquation);
-
///
/// Deletes a custom property by name
///
@@ -225,6 +302,13 @@ public List GetCustomProperties()
return list;
}
+ ///
+ /// Throws an exception if the actual property type doesn't match the expected type
+ ///
+ /// The name of the property to check
+ /// The expected property type
+ /// Whether to allow unknown/untyped properties
+ /// Thrown if the property type doesn't match the expected type
private void ThrowIfExpectedTypeMismatch(string name, swCustomInfoType_e expectedType, bool allowUnknown = false)
{
var type = (swCustomInfoType_e)BaseObject.GetType2(name);
From e53ecad4e969929c4ceb4bdafac1b4b1fe1867b1 Mon Sep 17 00:00:00 2001
From: GeKtvi <61162497+GeKtvi@users.noreply.github.com>
Date: Sat, 3 May 2025 19:35:15 +0300
Subject: [PATCH 3/3] Fixed date serialization in property setter
---
.../SolidWorks/CustomProperties/CustomPropertyEditor.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
index a08d6863..e3245dc5 100644
--- a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
+++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs
@@ -235,7 +235,7 @@ public void SetStringCustomProperty(string name, string value)
/// The name of the custom property
/// The date value to set
public void SetDateCustomProperty(string name, DateTime value)
- => SetCustomProperty(name, value.ToString("dd.MM.yyyy"), swCustomInfoType_e.swCustomInfoDate);
+ => SetCustomProperty(name, value.Date.ToShortDateString(), swCustomInfoType_e.swCustomInfoDate);
///
/// Sets an integer value to a number-type custom property