diff --git a/src/RhinoInside.Revit.External/DB/Extensions/Element.cs b/src/RhinoInside.Revit.External/DB/Extensions/Element.cs
index d4f8ec7a4..f2cca457c 100644
--- a/src/RhinoInside.Revit.External/DB/Extensions/Element.cs
+++ b/src/RhinoInside.Revit.External/DB/Extensions/Element.cs
@@ -48,7 +48,7 @@ public static bool IsEquivalent(this Element self, Element other)
if (ReferenceEquals(self, other))
return true;
- if (!self.IsValidObject || !other.IsValidObject)
+ if (!(self?.IsValidObject is true) || !(other?.IsValidObject is true))
return false;
if (self?.Id != other?.Id)
diff --git a/src/RhinoInside.Revit.External/Numerical.cs b/src/RhinoInside.Revit.External/Numerical.cs
index 9dc80d5c3..580e65fbe 100644
--- a/src/RhinoInside.Revit.External/Numerical.cs
+++ b/src/RhinoInside.Revit.External/Numerical.cs
@@ -121,6 +121,37 @@ internal static double Magnitude(double value)
{
return Math.Abs(value);
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double MinMagnitude(double x, double y)
+ {
+#if NET5_0_OR_GREATER
+ return Math.MinMagnitude(x, y);
+#else
+ double ax = Math.Abs(x);
+ double ay = Math.Abs(y);
+
+ return ax < ay ? x :
+ ax == ay ? (IsNegativeZero(x) ? -0.0 : y) :
+ double.IsNaN(ax) ? x : y;
+
+#endif
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double MaxMagnitude(double x, double y)
+ {
+#if NET5_0_OR_GREATER
+ return Math.MaxMagnitude(x, y);
+#else
+ double ax = Math.Abs(x);
+ double ay = Math.Abs(y);
+
+ return ax > ay ? x :
+ ax == ay ? (IsPositiveZero(x) ? +0.0 : y) :
+ double.IsNaN(ax) ? x : y;
+#endif
+ }
#endregion
#region Interval
@@ -131,12 +162,10 @@ internal static double Magnitude(double value)
/// The value to compare with .
/// if is less than ; otherwise
///
- /// This requires inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0.
+ /// This requires inputs to be propagated back to the caller and for -0.0 to be treated as less than +0.0.
///
- public static double Min(double x, double y) =>
- x < y ? x :
- x == y ? (IsNegativeZero(x) ? -0.0 : y) :
- double.IsNaN(y) ? x : y ;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Min(double x, double y) => Math.Min(x, y);
///
/// Computes the max point of the interval [, ].
@@ -145,12 +174,10 @@ public static double Min(double x, double y) =>
/// The value to compare with .
/// if is grater than ; otherwise
///
- /// This requires inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0.
+ /// This requires inputs to be propagated back to the caller and for -0.0 to be treated as less than +0.0.
///
- public static double Max(double x, double y) =>
- x > y ? x :
- x == y ? (IsPositiveZero(x) ? +0.0 : y) :
- double.IsNaN(y) ? x : y ;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Max(double x, double y) => Math.Max(x, y);
///
/// Computes the mean point of the interval [, ].
@@ -165,17 +192,17 @@ public static double Mean(double x, double y)
{
if (x == y) return x;
- var X = Math.Abs(x);
- var Y = Math.Abs(y);
+ var ax = Math.Abs(x);
+ var ay = Math.Abs(y);
//// Avoids oveflow
- //if (X <= double.MaxValue / 2 && Y <= double.MaxValue / 2)
+ //if (ax <= double.MaxValue * 0.5 && ay <= double.MaxValue * 0.5)
// return (x + y) * 0.5;
- if (X < Constant.Upsilon)
+ if (ax < Constant.Upsilon)
return x + (y * 0.5);
- if (Y < Constant.Upsilon)
+ if (ay < Constant.Upsilon)
return (x * 0.5) + y;
return (x * 0.5) + (y * 0.5);
@@ -227,11 +254,52 @@ public static double Mix(double x, double y, double t)
/// The lower bound of the result.
/// The upper bound of the result.
/// Clamped or if equals .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Clamp(double value, double min, double max)
{
return value < min ? min : max < value ? max : value;
}
#endregion
+
+ #region Number
+ ///
+ /// Computes the min point of the interval [, ].
+ ///
+ /// The value to compare with .
+ /// The value to compare with .
+ /// if is less than ; otherwise
+ ///
+ /// This requires inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double MinNumber(double x, double y) =>
+#if NET5_0_OR_GREATER
+ double.MinNumber(x, y);
+#else
+ x < y ? x :
+ x == y ? (IsNegativeZero(x) ? -0.0 : y) :
+ double.IsNaN(y) ? x : y ;
+#endif
+
+ ///
+ /// Computes the max point of the interval [, ].
+ ///
+ /// The value to compare with .
+ /// The value to compare with .
+ /// if is grater than ; otherwise
+ ///
+ /// This requires inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double MaxNumber(double x, double y) =>
+#if NET5_0_OR_GREATER
+ double.MaxNumber(x, y);
+#else
+ x > y ? x :
+ x == y ? (IsPositiveZero(x) ? +0.0 : y) :
+ double.IsNaN(y) ? x : y ;
+#endif
+ #endregion
}
///
diff --git a/src/RhinoInside.Revit.GH/Components/Views/Extents.cs b/src/RhinoInside.Revit.GH/Components/Views/Extents.cs
index 57ee54a56..cc9e06ad3 100644
--- a/src/RhinoInside.Revit.GH/Components/Views/Extents.cs
+++ b/src/RhinoInside.Revit.GH/Components/Views/Extents.cs
@@ -237,17 +237,17 @@ static void GetViewRangeOffsets(ARDB.View view, out double backOffset, out doubl
{
case ARDB.View3D view3D:
if (view3D.IsPerspective)
- frontOffset = Arithmetic.Min(frontOffset, view3D.CropBox.Max.Z);
+ frontOffset = Arithmetic.MinNumber(frontOffset, view3D.CropBox.Max.Z);
break;
case ARDB.ViewPlan viewPlan:
var interval = viewPlan.GetViewRangeInterval();
- backOffset = Arithmetic.Max(backOffset, interval.Left.Bound - view.Origin.Z);
- frontOffset = Arithmetic.Min(frontOffset, interval.Right.Bound - view.Origin.Z);
+ backOffset = Arithmetic.MaxNumber(backOffset, interval.Left.Bound - view.Origin.Z);
+ frontOffset = Arithmetic.MinNumber(frontOffset, interval.Right.Bound - view.Origin.Z);
break;
case ARDB.ViewSection viewSection:
- frontOffset = Arithmetic.Min(frontOffset, viewSection.CropBox.Max.Z);
+ frontOffset = Arithmetic.MinNumber(frontOffset, viewSection.CropBox.Max.Z);
break;
}
}
diff --git a/src/RhinoInside.Revit.GH/Types/Element.Activator.cs b/src/RhinoInside.Revit.GH/Types/Element.Activator.cs
index a66c25e58..d3547d79d 100644
--- a/src/RhinoInside.Revit.GH/Types/Element.Activator.cs
+++ b/src/RhinoInside.Revit.GH/Types/Element.Activator.cs
@@ -313,6 +313,7 @@ public static Element FromReference(ARDB.Document doc, ARDB.Reference reference)
{ typeof(ARDB.CombinableElement), (element)=> new CombinableElement (element as ARDB.CombinableElement) },
{ typeof(ARDB.GeomCombination), (element)=> new GeomCombination (element as ARDB.GeomCombination) },
{ typeof(ARDB.GenericForm), (element)=> new GenericForm (element as ARDB.GenericForm) },
+ { typeof(ARDB.ModelText), (element)=> new ModelText (element as ARDB.ModelText) },
{ typeof(ARDB.DatumPlane), (element)=> new DatumPlane (element as ARDB.DatumPlane) },
{ typeof(ARDB.Level), (element)=> new Level (element as ARDB.Level) },
diff --git a/src/RhinoInside.Revit.GH/Types/Opening.cs b/src/RhinoInside.Revit.GH/Types/HostObjects/Opening.cs
similarity index 100%
rename from src/RhinoInside.Revit.GH/Types/Opening.cs
rename to src/RhinoInside.Revit.GH/Types/HostObjects/Opening.cs
diff --git a/src/RhinoInside.Revit.GH/Types/CombinableElement.cs b/src/RhinoInside.Revit.GH/Types/Model/CombinableElement.cs
similarity index 100%
rename from src/RhinoInside.Revit.GH/Types/CombinableElement.cs
rename to src/RhinoInside.Revit.GH/Types/Model/CombinableElement.cs
diff --git a/src/RhinoInside.Revit.GH/Types/CurveElement.cs b/src/RhinoInside.Revit.GH/Types/Model/CurveElement.cs
similarity index 100%
rename from src/RhinoInside.Revit.GH/Types/CurveElement.cs
rename to src/RhinoInside.Revit.GH/Types/Model/CurveElement.cs
diff --git a/src/RhinoInside.Revit.GH/Types/Group.cs b/src/RhinoInside.Revit.GH/Types/Model/Group.cs
similarity index 100%
rename from src/RhinoInside.Revit.GH/Types/Group.cs
rename to src/RhinoInside.Revit.GH/Types/Model/Group.cs
diff --git a/src/RhinoInside.Revit.GH/Types/Model/ModelText.cs b/src/RhinoInside.Revit.GH/Types/Model/ModelText.cs
new file mode 100644
index 000000000..f6fb4daa9
--- /dev/null
+++ b/src/RhinoInside.Revit.GH/Types/Model/ModelText.cs
@@ -0,0 +1,62 @@
+using System;
+using Rhino.Geometry;
+using ARDB = Autodesk.Revit.DB;
+
+namespace RhinoInside.Revit.GH.Types
+{
+ using Convert.Geometry;
+ using External.DB.Extensions;
+
+ [Kernel.Attributes.Name("Model Text")]
+ public class ModelText : GeometricElement
+ {
+ protected override Type ValueType => typeof(ARDB.ModelText);
+ public new ARDB.ModelText Value => base.Value as ARDB.ModelText;
+
+ public ModelText() : base() { }
+ public ModelText(ARDB.ModelText modelText) : base(modelText) { }
+
+ #region Location
+ public override Plane Location
+ {
+ get
+ {
+ if (Value is ARDB.ModelText modelText)
+ {
+ using (var options = new ARDB.Options { DetailLevel = ARDB.ViewDetailLevel.Undefined })
+ {
+ var geometry = modelText.get_Geometry(options);
+ if (geometry.TryGetLocation(out var gO, out var gX, out var gY))
+ {
+ var xform = ARDB.Transform.Identity;
+ xform.SetAlignCoordSystem
+ (
+ ARDB.XYZ.Zero, External.DB.UnitXYZ.BasisX, External.DB.UnitXYZ.BasisY, External.DB.UnitXYZ.BasisZ,
+ gO, gX, gY, gX.CrossProduct(gY).ToUnitXYZ()
+ );
+
+ var box = geometry.GetBoundingBox(xform);
+
+ var origin = (box.GetCenter() - box.Transform.BasisZ * 0.5 * (box.Max.Z - box.Min.Z));
+ switch (modelText.HorizontalAlignment)
+ {
+ case ARDB.HorizontalAlign.Left: origin = box.GetCorners()[3]; break;
+ case ARDB.HorizontalAlign.Right: origin = box.GetCorners()[2]; break;
+ case ARDB.HorizontalAlign.Center: origin = (box.GetCorners()[3] + box.GetCorners()[2]) * 0.5; break;
+ }
+
+ return new Plane(origin.ToPoint3d(), box.Transform.BasisX.ToVector3d(), box.Transform.BasisY.ToVector3d());
+ }
+ }
+
+ var bbox = BoundingBox;
+ if (bbox.IsValid)
+ return new Plane(BoundingBox.Center, Vector3d.XAxis, Vector3d.YAxis);
+ }
+
+ return NaN.Plane;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/src/RhinoInside.Revit.GH/Types/SketchPlane.cs b/src/RhinoInside.Revit.GH/Types/Model/SketchPlane.cs
similarity index 100%
rename from src/RhinoInside.Revit.GH/Types/SketchPlane.cs
rename to src/RhinoInside.Revit.GH/Types/Model/SketchPlane.cs
diff --git a/src/RhinoInside.Revit.GH/Types/Views/ViewFrame.cs b/src/RhinoInside.Revit.GH/Types/Views/ViewFrame.cs
index b59598c14..0698b0c72 100644
--- a/src/RhinoInside.Revit.GH/Types/Views/ViewFrame.cs
+++ b/src/RhinoInside.Revit.GH/Types/Views/ViewFrame.cs
@@ -436,16 +436,16 @@ public override bool CastTo(ref Q target)
public Point3d Min => new Point3d
(
- Arithmetic.Min( Value.FrustumLeft, Bound[AxisX].T0),
- Arithmetic.Min( Value.FrustumBottom, Bound[AxisY].T0),
- Arithmetic.Min(-Value.FrustumFar, Bound[AxisZ].T0)
+ Arithmetic.MinNumber( Value.FrustumLeft, Bound[AxisX].T0),
+ Arithmetic.MinNumber( Value.FrustumBottom, Bound[AxisY].T0),
+ Arithmetic.MinNumber(-Value.FrustumFar, Bound[AxisZ].T0)
);
public Point3d Max => new Point3d
(
- Arithmetic.Max( Value.FrustumRight, Bound[AxisX].T1),
- Arithmetic.Max( Value.FrustumTop, Bound[AxisY].T1),
- Arithmetic.Max(-Value.FrustumNear, Bound[AxisZ].T1)
+ Arithmetic.MaxNumber( Value.FrustumRight, Bound[AxisX].T1),
+ Arithmetic.MaxNumber( Value.FrustumTop, Bound[AxisY].T1),
+ Arithmetic.MaxNumber(-Value.FrustumNear, Bound[AxisZ].T1)
);
internal ARDB.BoundingBoxXYZ ToBoundingBoxXYZ(bool ensurePositiveY = false)
diff --git a/src/RhinoInside.Revit/Convert/Units/UnitScale.cs b/src/RhinoInside.Revit/Convert/Units/UnitScale.cs
index 4d77ea6c5..a426dcd0b 100644
--- a/src/RhinoInside.Revit/Convert/Units/UnitScale.cs
+++ b/src/RhinoInside.Revit/Convert/Units/UnitScale.cs
@@ -8,6 +8,8 @@
namespace RhinoInside.Revit.Convert.Units
{
+ using Numerical;
+
[DebuggerDisplay("{Antecedent} ∶ {Consequent} ({Quotient})")]
readonly struct Ratio : IEquatable
{
@@ -391,10 +393,7 @@ public static double Convert(double value, UnitScale from, UnitScale to)
var den = f * T;
// Multiply value by resulting ratio considering magnitude.
- if (Math.Abs(num) < Math.Abs(value))
- return num * (value / den);
- else
- return value * (num / den);
+ return Arithmetic.MinMagnitude(num, value) * (Arithmetic.MaxMagnitude(num, value) / den);
}
public override string ToString() => Name ?? ((UnitSystem) this).ToString();
@@ -458,6 +457,7 @@ internal static void SetUnitScale(RhinoDoc doc, ActiveSpace space, UnitScale val
}
doc.ModelSpaceHatchScale *= scaleFactor;
+ doc.Linetypes.LinetypeScale *= scaleFactor;
foreach (var style in doc.DimStyles)
{