Utils
Utility class for operating on units of measure.
using Autodesk.DesignScript.Runtime;
using System;
using System.Globalization;
using System.Text.RegularExpressions;
namespace DynamoUnits
{
[SupressImportIntoVM]
[Obsolete("This class will be removed in Dynamo 3.0 - - please use the Unit.Utilities class and associated methods")]
public class Utils
{
private const int ROUND_DIGITS = 5;
private const double EPSILON = 1E-05;
public static string ParseWholeInchesToString(double value)
{
double double = (value < 0) ? Math.Abs(Math.Ceiling(value)) : Math.Abs(Math.Floor(value));
if (double.AlmostEquals(0, 1E-05))
return "";
return double.ToString();
}
public static string ParsePartialInchesToString(double value, double precision)
{
return (value < 0) ? CreateFraction(Math.Abs(value - Math.Ceiling(value)), 0.015625) : CreateFraction(Math.Abs(value - Math.Floor(value)), 0.015625);
}
public static string CreateFraction(double value, double precision)
{
double num = 0;
num = Math.Round(value / precision);
double num2 = 1 / precision;
if (num.AlmostEquals(num2, 1E-05))
return "1";
if (num != 0) {
while (num % 2 == 0) {
num /= 2;
num2 /= 2;
}
return $"{num}""{num2}";
}
return "";
}
private static double RoundToSignificantDigits(double d, int digits)
{
if (d == 0)
return 0;
double num = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return num * Math.Round(d / num, digits);
}
public static double ParseUnit(string value, string unitSymbol)
{
if (value.ToLower().Contains(unitSymbol))
value = value.Replace(unitSymbol, "");
if (!double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double result))
return 0;
return result;
}
public static double FromFeetAndFractionalInches(string value)
{
double num = 0;
ParseLengthFromString(value.ToString(), out double feet, out double inch, out double _, out double _, out double _, out double numerator, out double denominator);
if (denominator != 0)
num = numerator / denominator;
double num2 = 1;
if (value.StartsWith("-"))
num2 *= -1;
if (feet < 0)
return feet - inch / 12 - num / 12;
return feet + inch / 12 + num / 12;
}
public static string ToFeetAndFractionalInches(double decimalFeet)
{
double num = 0;
double num2 = 0;
if (decimalFeet < 0) {
num = Math.Ceiling(decimalFeet);
num2 = ((num != 0) ? (num - decimalFeet) : decimalFeet);
} else {
num = Math.Floor(decimalFeet);
num2 = decimalFeet - num;
}
string text = ToFractionalInches(Math.Round(num2 * 12, 5));
switch (text) {
case "11 1\"":
case "12\"":
num += 1;
text = "0\"";
break;
case "-11 1\"":
case "-12\"":
num -= 1;
text = "0\"";
break;
}
string arg = "";
if (num != 0)
arg = $"{num}""";
if (num.AlmostEquals(0, 1E-05) && (num2 * 12).AlmostEquals(0, 1E-05))
arg = "0'";
return $"{arg}""{text}".Trim();
}
public static string ToFractionalInches(double decimalInches)
{
decimalInches = RoundToSignificantDigits(decimalInches, 5);
string text = ParseWholeInchesToString(decimalInches);
string text2 = ParsePartialInchesToString(decimalInches, 0.015625);
string arg = (decimalInches < 0) ? "-" : "";
if (string.IsNullOrEmpty(text) && string.IsNullOrEmpty(text2))
return "0\"";
if (string.IsNullOrEmpty(text2))
return $"{arg}{text}""".Trim();
if (string.IsNullOrEmpty(text))
return $"{arg}{text2}""".Trim();
if (text2 == "1") {
text2 = "";
text = (double.Parse(text) + 1).ToString(CultureInfo.InvariantCulture);
return $"{arg}{text}""".Trim();
}
return $"{arg}{text}""{text2}""".Trim();
}
public static string ToFeetAndDecimalInches(double decimalFeet)
{
double num = 0;
double num2 = 0;
if (decimalFeet < 0) {
num = Math.Ceiling(decimalFeet);
num2 = ((num != 0) ? (num - decimalFeet) : decimalFeet);
} else {
num = Math.Floor(decimalFeet);
num2 = decimalFeet - num;
}
string str = Math.Round(num2 * 12, 5).ToString(BaseUnit.GeneralNumberFormat, CultureInfo.InvariantCulture);
if (num2.AlmostEquals(1, 1E-05)) {
num += 1;
str = "0";
} else if (num2.AlmostEquals(-1, 1E-05)) {
num -= 1;
str = "0";
}
string arg = "";
if (num != 0)
arg = $"{num}""";
if (num.AlmostEquals(0, 1E-05) && (num2 * 12).AlmostEquals(0, 1E-05))
arg = "0'";
str += "\"";
return $"{arg}""{str}".Trim();
}
public static bool ParseLengthInFeetFromString(string value, out double feet, out double numerator, out double denominator)
{
string pattern = "(\\A((?<ft>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?))\\Z)|(\\A(?<ft>(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)('|ft)?)\\Z)";
feet = 0;
numerator = 0;
denominator = 0;
Regex regex = new Regex(pattern, RegexOptions.None);
Match match = regex.Match(value.Trim().ToLower());
if (match.Success) {
double.TryParse(match.Groups["ft"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out feet);
double.TryParse(match.Groups["num"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out numerator);
double.TryParse(match.Groups["den"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out denominator);
return true;
}
return false;
}
public static void ParseLengthFromString(string value, out double feet, out double inch, out double m, out double cm, out double mm, out double numerator, out double denominator)
{
string pattern = "(((?<ft>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)('|ft))*\\s*((?<in>(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)(\"|in))|(?<in>(?<wholeInch>(\\+|-)?\\d{1,}?)(\\s|-)*(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)(\"|in))|(?<in>(?<wholeInch>(\\+|-)?\\d+([.,]\\d{1,})?)( ?)(\"|in)))?)*((?<m>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)m($|\\s))*((?<cm>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)cm($|\\s))*((?<mm>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)mm($|\\s))*";
feet = 0;
inch = 0;
m = 0;
cm = 0;
mm = 0;
numerator = 0;
denominator = 0;
Regex regex = new Regex(pattern, RegexOptions.None);
Match match = regex.Match(value.Trim().ToLower());
if (match.Success) {
double.TryParse(match.Groups["ft"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out feet);
double.TryParse(match.Groups["wholeInch"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out inch);
double.TryParse(match.Groups["num"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out numerator);
double.TryParse(match.Groups["den"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out denominator);
double.TryParse(match.Groups["m"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out m);
double.TryParse(match.Groups["cm"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cm);
double.TryParse(match.Groups["mm"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out mm);
}
}
public static void ParseAreaFromString(string value, out double square_inch, out double square_foot, out double square_millimeter, out double square_centimeter, out double square_meter)
{
square_inch = 0;
square_foot = 0;
square_millimeter = 0;
square_centimeter = 0;
square_meter = 0;
Regex regex = new Regex("((?<square_inches>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(in2|sqin|in²))*\\s*((?<square_feet>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(ft2|sqft|ft²))*\\s*((?<square_millimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(mm2|sqmm|mm²))*\\s*((?<square_centimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(cm2|sqcm|cm²))*\\s*((?<square_meters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(m2|sqm|m²))*\\s*", RegexOptions.None);
Match match = regex.Match(value.Trim().ToLower());
if (match.Success) {
double.TryParse(match.Groups["square_inches"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_inch);
double.TryParse(match.Groups["square_feet"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_foot);
double.TryParse(match.Groups["square_millimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_millimeter);
double.TryParse(match.Groups["square_centimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_centimeter);
double.TryParse(match.Groups["square_meters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_meter);
}
}
public static void ParseVolumeFromString(string value, out double cubic_inch, out double cubic_foot, out double cubic_millimeter, out double cubic_centimeter, out double cubic_meter)
{
cubic_inch = 0;
cubic_foot = 0;
cubic_millimeter = 0;
cubic_centimeter = 0;
cubic_meter = 0;
Regex regex = new Regex("((?<cubic_inches>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(in3|cuin|in³))*\\s*((?<cubic_feet>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(ft3|cuft|ft³))*\\s*((?<cubic_millimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(mm3|cumm|mm³))*\\s*((?<cubic_centimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(cm3|cucm|cm³))*\\s*((?<cubic_meters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(m3|cum|m³))*\\s*", RegexOptions.None);
Match match = regex.Match(value.Trim().ToLower());
if (match.Success) {
double.TryParse(match.Groups["cubic_inches"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_inch);
double.TryParse(match.Groups["cubic_feet"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_foot);
double.TryParse(match.Groups["cubic_millimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_millimeter);
double.TryParse(match.Groups["cubic_centimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_centimeter);
double.TryParse(match.Groups["cubic_meters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_meter);
}
}
}
}