diff --git a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
index f7e6cf1e..b9ea7657 100644
--- a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
+++ b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs
@@ -169,6 +169,11 @@ public enum SolidDnaErrorCode
///
SolidWorksModelGetConfigurationError = 11014,
+ ///
+ /// Error occurred while trying to get a custom property value from a SolidWorks model
+ ///
+ 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..e3245dc5 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,12 @@ 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
///
@@ -26,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
@@ -39,18 +47,156 @@ 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
// 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;
}
+ ///
+ /// 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
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoText, true);
+
+ _ = BaseObject.Get5(name, false, out var val, out var resolvedVal, out _);
+
+ 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
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoDate);
+
+
+ _ = 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
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber);
+
+
+ _ = 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
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber);
+
+
+ _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _);
+
+ 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
+
+ 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();
+ }
+ }
+
+ ///
+ /// 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
+
+ if (IsTypeCheckEnabled)
+ ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoEquation, true);
+
+ _ = BaseObject.Get5(name, false, out var val, out _, out _);
+
+ 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
+
+ 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 +218,57 @@ 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);
}
+ ///
+ /// 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.Date.ToShortDateString(), 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
///
@@ -107,5 +301,27 @@ public List GetCustomProperties()
// Return the list
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);
+
+ 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}"));
+ }
+ }
}
}