From 795529e61c82933e4fa96a17995b9fc4fa8288eb Mon Sep 17 00:00:00 2001 From: kike-garbo Date: Thu, 27 Jul 2023 13:16:00 +0200 Subject: [PATCH 1/3] Fix on 'Reference Annotations' - When used on a wall with tagged inserts. - When used on linked elements. --- docs/pages/_en/1.0/reference/release-notes.md | 2 +- .../Components/Annotations/References.cs | 84 ++++++++++++------- .../Types/Annotations/Annotation.cs | 2 +- .../Types/Annotations/Dimension.cs | 2 +- .../Types/Annotations/SpatialElementTag.cs | 6 +- .../Types/Annotations/TagElement.cs | 2 +- .../Types/GeometryObject.cs | 9 +- src/RhinoInside.Revit.GH/Types/Reference.cs | 25 +++--- 8 files changed, 77 insertions(+), 55 deletions(-) diff --git a/docs/pages/_en/1.0/reference/release-notes.md b/docs/pages/_en/1.0/reference/release-notes.md index df6dac8e1..fcfe0c4f5 100644 --- a/docs/pages/_en/1.0/reference/release-notes.md +++ b/docs/pages/_en/1.0/reference/release-notes.md @@ -16,7 +16,7 @@ group: Deployment & Configs - Added 'Add Toposolid Sub-Division' component. - Added 'Component References' component. - Added 'Component Reference Plane' component. -- Added 'Element Annotations' component. +- Added 'Reference Annotations' component. - Improved 'Host Shape' performance. {% endcapture %} diff --git a/src/RhinoInside.Revit.GH/Components/Annotations/References.cs b/src/RhinoInside.Revit.GH/Components/Annotations/References.cs index d71c90f4b..07a0f0942 100644 --- a/src/RhinoInside.Revit.GH/Components/Annotations/References.cs +++ b/src/RhinoInside.Revit.GH/Components/Annotations/References.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Linq; using Grasshopper.Kernel; using ARDB = Autodesk.Revit.DB; namespace RhinoInside.Revit.GH.Components.Annotations { using External.DB; + using External.DB.Extensions; [ComponentVersion(introduced: "1.12")] public class AnnotationReferences : ZuiComponent @@ -17,7 +19,7 @@ public class AnnotationReferences : ZuiComponent public AnnotationReferences() : base ( name: "Annotation References", - nickname: "References", + nickname: "A-References", description: string.Empty, category: "Revit", subCategory: "Annotate" @@ -70,16 +72,16 @@ protected override void TrySolveInstance(IGH_DataAccess DA) } [ComponentVersion(introduced: "1.16")] - public class ElementAnnotations : ZuiComponent + public class ReferenceAnnotations : ZuiComponent { public override Guid ComponentGuid => new Guid("2AB03AAF-98E4-4EF5-A84B-918B64E5908D"); public override GH_Exposure Exposure => GH_Exposure.quinary; protected override string IconTag => string.Empty; - public ElementAnnotations() : base + public ReferenceAnnotations() : base ( - name: "Element Annotations", - nickname: "E-Annotations", + name: "Reference Annotations", + nickname: "R-Annotations", description: string.Empty, category: "Revit", subCategory: "Annotate" @@ -91,10 +93,10 @@ public ElementAnnotations() : base { new ParamDefinition ( - new Parameters.GraphicalElement() + new Parameters.GeometryObject() { - Name = "Element", - NickName = "E", + Name = "Reference", + NickName = "R", } ), new ParamDefinition @@ -111,14 +113,6 @@ public ElementAnnotations() : base protected override ParamDefinition[] Outputs => outputs; static readonly ParamDefinition[] outputs = { - new ParamDefinition - ( - new Parameters.GraphicalElement() - { - Name = "Element", - NickName = "E", - }, ParamRelevance.Secondary - ), new ParamDefinition ( new Parameters.Dimension() @@ -143,8 +137,9 @@ public ElementAnnotations() : base protected override void TrySolveInstance(IGH_DataAccess DA) { - if (!Params.GetData(DA, "Element", out Types.GraphicalElement element, x => x.IsValid)) return; - else Params.TrySetData(DA, "Element", () => element); + if (!Params.GetData(DA, "Reference", out Types.GeometryObject reference, x => x.IsValid)) return; + if (!reference.CastTo(out Types.GraphicalElement referenceElement)) return; + if (!Params.TryGetData(DA, "View", out Types.View view, x => x.IsValid)) return; var _Dimensions_ = Params.IndexOfOutputParam("Dimensions"); @@ -164,24 +159,51 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (typesList.Count == 0) return; var filter = CompoundElementFilter.ElementClassFilter(typesList); - if (view is object) - filter = filter.Intersect(new ARDB.ElementOwnerViewFilter(view.Id)); - - var dimensions = new List(); - var tags = new List(); + IEnumerable annotationElements = null; - foreach (var id in element.Value.GetDependentElements(filter.ThatExcludes(element.Id))) + if (view is object) { - switch (element.Document.GetElement(id)) + if (view.Document.IsEquivalent(reference.Document)) + { + filter = filter.Intersect(new ARDB.ElementOwnerViewFilter(view.Id, inverted: false)); + annotationElements = referenceElement.Value.GetDependentElements(filter.ThatExcludes(reference.Id)).Select(reference.Document.GetElement); + } + else if (view.Document.IsEquivalent(reference.ReferenceDocument)) { - case ARDB.IndependentTag independentTag: - tags.Add(independentTag); break; + using (var collector = new ARDB.FilteredElementCollector(view.Document).WherePasses(filter)) + annotationElements = collector.OwnedByView(view.Id).ToElements(); + } + } + else + { + filter = filter.Intersect(new ARDB.ElementOwnerViewFilter(ElementIdExtension.Invalid, inverted: true)); + annotationElements = referenceElement.Value.GetDependentElements(filter.ThatExcludes(reference.Id)).Select(reference.Document.GetElement); + } - case ARDB.SpatialElementTag spatialElementTag: - tags.Add(spatialElementTag); break; + var dimensions = new List(); + var tags = new List(); - case ARDB.Dimension dimension: - dimensions.Add(dimension); break; + foreach (var annotationElement in annotationElements) + { + var dependent = reference.GetElement(annotationElement); + if (dependent is Types.IAnnotationReferencesAccess annotation) + { + foreach (var annotationReference in annotation.References) + { + if (!annotationReference.IsEquivalent(reference)) + continue; + + switch (dependent) + { + case Types.Dimension dimension: + dimensions.Add(dimension); break; + + case Types.TagElement tag: + tags.Add(tag); break; + } + + break; + } } } diff --git a/src/RhinoInside.Revit.GH/Types/Annotations/Annotation.cs b/src/RhinoInside.Revit.GH/Types/Annotations/Annotation.cs index 9799cc447..8e2f87cc3 100644 --- a/src/RhinoInside.Revit.GH/Types/Annotations/Annotation.cs +++ b/src/RhinoInside.Revit.GH/Types/Annotations/Annotation.cs @@ -15,7 +15,7 @@ public interface IGH_Annotation : IGH_GraphicalElement interface IAnnotationReferencesAccess { /// - /// Returns an array of geometric references to which the dimension is attached. + /// Returns an array of geometric references to which the annotation is attached. /// GeometryObject[] References { get; } } diff --git a/src/RhinoInside.Revit.GH/Types/Annotations/Dimension.cs b/src/RhinoInside.Revit.GH/Types/Annotations/Dimension.cs index fd574622e..d47326324 100644 --- a/src/RhinoInside.Revit.GH/Types/Annotations/Dimension.cs +++ b/src/RhinoInside.Revit.GH/Types/Annotations/Dimension.cs @@ -122,7 +122,7 @@ public override Curve Curve public GeometryObject[] References => Value?.References. Cast(). - Select(x => GeometryObject.FromReference(ReferenceDocument, x)). + Select(GetGeometryObjectFromReference). ToArray(); #endregion diff --git a/src/RhinoInside.Revit.GH/Types/Annotations/SpatialElementTag.cs b/src/RhinoInside.Revit.GH/Types/Annotations/SpatialElementTag.cs index 7aab300c7..ccb136629 100644 --- a/src/RhinoInside.Revit.GH/Types/Annotations/SpatialElementTag.cs +++ b/src/RhinoInside.Revit.GH/Types/Annotations/SpatialElementTag.cs @@ -182,7 +182,7 @@ public override GeometryObject[] References if (Value is ARDB.AreaTag tag && tag.Area is ARDB.Area area) { using (var reference = ARDB.Reference.ParseFromStableRepresentation(area.Document, area.UniqueId)) - return new GeometryObject[] { GeometryElement.FromReference(area.Document, reference) }; + return new GeometryObject[] { GetGeometryObjectFromReference(reference) }; } return default; @@ -214,7 +214,7 @@ public override GeometryObject[] References } else { - try { return new GeometryObject[] { GeometryObject.FromElementId(ReferenceDocument, tag.TaggedLocalRoomId) }; } + try { return new GeometryObject[] { GeometryObject.FromElementId(Document, tag.TaggedLocalRoomId) }; } catch { } } } @@ -242,7 +242,7 @@ public override GeometryObject[] References if (Value is ARDB.Mechanical.SpaceTag tag && tag.Space is ARDB.Mechanical.Space space) { using (var reference = ARDB.Reference.ParseFromStableRepresentation(space.Document, space.UniqueId)) - return new GeometryObject[] { GeometryElement.FromReference(space.Document, reference) }; + return new GeometryObject[] { GetGeometryObjectFromReference(reference) }; } return default; diff --git a/src/RhinoInside.Revit.GH/Types/Annotations/TagElement.cs b/src/RhinoInside.Revit.GH/Types/Annotations/TagElement.cs index cd575d1da..217d8b869 100644 --- a/src/RhinoInside.Revit.GH/Types/Annotations/TagElement.cs +++ b/src/RhinoInside.Revit.GH/Types/Annotations/TagElement.cs @@ -61,7 +61,7 @@ public override Plane Location public override GeometryObject[] References => Value?.GetTaggedReferences(). Cast(). - Select(x => GeometryObject.FromReference(ReferenceDocument, x)). + Select(GetGeometryObjectFromReference). ToArray(); #endregion diff --git a/src/RhinoInside.Revit.GH/Types/GeometryObject.cs b/src/RhinoInside.Revit.GH/Types/GeometryObject.cs index 505b9436a..5f60bfa9e 100644 --- a/src/RhinoInside.Revit.GH/Types/GeometryObject.cs +++ b/src/RhinoInside.Revit.GH/Types/GeometryObject.cs @@ -363,6 +363,13 @@ public static GeometryObject FromLinkElementId(ARDB.Document document, ARDB.Link return default; } + public virtual ARDB.Reference GetDefaultReference() => _Reference; + + public bool IsEquivalent(GeometryObject other) => other is object && + Id.Equals(other.Id) && + Document.IsEquivalent(other.Document) && + Equals(GetType(), other.GetType()); + public GraphicsStyle GraphicsStyle => Value is ARDB.GeometryObject geometryObject ? geometryObject.GraphicsStyleId.IsValid() ? GetElement(geometryObject.GraphicsStyleId) : new GraphicsStyle() : null; @@ -371,8 +378,6 @@ public static GeometryObject FromLinkElementId(ARDB.Document document, ARDB.Link /// Accurate axis aligned for computation. /// public virtual BoundingBox BoundingBox => GetBoundingBox(Transform.Identity); - - public virtual ARDB.Reference GetDefaultReference() => _Reference; } [Name("Element")] diff --git a/src/RhinoInside.Revit.GH/Types/Reference.cs b/src/RhinoInside.Revit.GH/Types/Reference.cs index 1567fdf76..22ea9bd6c 100755 --- a/src/RhinoInside.Revit.GH/Types/Reference.cs +++ b/src/RhinoInside.Revit.GH/Types/Reference.cs @@ -171,17 +171,12 @@ protected Reference(ARDB.Document doc, object value) : base(doc, value) { } protected internal ARDB.Reference GetAbsoluteReference(ARDB.Reference reference) { - if (reference.LinkedElementId == ElementIdExtension.Invalid) + if (IsLinked) { - if (reference.ElementId != Id) - throw new ArgumentException("Invalid Reference", nameof(reference)); - - if (IsLinked) + if (reference.LinkedElementId == ElementIdExtension.Invalid) return reference.CreateLinkReference(ReferenceDocument, ReferenceId, Document); - } - else - { - if (reference.ElementId != ReferenceId) + + if (reference.LinkedElementId != ReferenceId) throw new ArgumentException("Invalid Reference", nameof(reference)); } @@ -205,13 +200,13 @@ protected internal T GetElement(ARDB.Element element) where T : Element { if (element.IsValid()) { - if (!Document.IsEquivalent(element.Document)) - throw new Exceptions.RuntimeArgumentException($"Invalid {typeof(T)} Document", nameof(element)); + if (IsLinked && Document.IsEquivalent(element.Document)) + return (T) Element.FromLinkElementId(ReferenceDocument, new ARDB.LinkElementId(ReferenceId, element.Id)); - return (T) - (IsLinked ? - Element.FromLinkElementId(ReferenceDocument, new ARDB.LinkElementId(ReferenceId, element.Id)) : - Element.FromElement(element)); + if (!ReferenceDocument.IsEquivalent(element.Document)) + throw new Exceptions.RuntimeArgumentException(nameof(element), $"Invalid {typeof(T)} Document"); + + return (T) Element.FromElement(element); } return null; From 7a38bec98d8bd3e2482ff525116f637419d68af3 Mon Sep 17 00:00:00 2001 From: kike-garbo Date: Thu, 27 Jul 2023 13:18:22 +0200 Subject: [PATCH 2/3] `Types.Group.Location` is too slow to determine context menu visibility. --- .../Parameters/GraphicalElement.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/RhinoInside.Revit.GH/Parameters/GraphicalElement.cs b/src/RhinoInside.Revit.GH/Parameters/GraphicalElement.cs index 88a923c02..76ce47d7b 100755 --- a/src/RhinoInside.Revit.GH/Parameters/GraphicalElement.cs +++ b/src/RhinoInside.Revit.GH/Parameters/GraphicalElement.cs @@ -323,8 +323,9 @@ protected override void Menu_AppendBakeItem(ToolStripDropDown menu) if (VolatileData.DataCount == 1) { - var cplane = VolatileData.AllData(true).FirstOrDefault() is Types.GraphicalElement element && - element.Location.IsValid; + // `Types.Group.Location` is too slow for this purpose. + //var cplane = VolatileData.AllData(true).FirstOrDefault() is Types.GraphicalElement element && element.Location.IsValid; + var cplane = VolatileData.AllData(true).FirstOrDefault() is Types.GraphicalElement element && element.IsValid; Menu_AppendItem(menu, $"Set CPlane", Menu_SetCPlane, cplane, false); } @@ -515,20 +516,22 @@ private void Menu_HighlightElements(object sender, EventArgs e) private void Menu_SetCPlane(object sender, EventArgs e) { - if (VolatileData.AllData(true).FirstOrDefault() is Types.GraphicalElement element) + if + ( + VolatileData.AllData(true).FirstOrDefault() is Types.GraphicalElement element && + Rhino.RhinoDoc.ActiveDoc is Rhino.RhinoDoc doc && + (doc.Views.ActiveView ?? doc.Views.FirstOrDefault()) is RhinoView view && + view.ActiveViewport is RhinoViewport vport + ) { - if - ( - Rhino.RhinoDoc.ActiveDoc is Rhino.RhinoDoc doc && - (doc.Views.ActiveView ?? doc.Views.FirstOrDefault()) is RhinoView view && - view.ActiveViewport is RhinoViewport vport - ) + var location = element.Location; + if (location.IsValid) { view.BringToFront(); doc.Views.ActiveView = view; var cplane = vport.GetConstructionPlane(); - cplane.Plane = element.Location; + cplane.Plane = location; vport.PushConstructionPlane(cplane); view.Redraw(); From 417f0310afac366fbbad065763c9e008dd6365c3 Mon Sep 17 00:00:00 2001 From: kike-garbo Date: Thu, 27 Jul 2023 13:19:00 +0200 Subject: [PATCH 3/3] Updated 'Element Owner View'. --- src/RhinoInside.Revit.GH/Components/Element/View.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RhinoInside.Revit.GH/Components/Element/View.cs b/src/RhinoInside.Revit.GH/Components/Element/View.cs index bf7404110..ff7d62053 100644 --- a/src/RhinoInside.Revit.GH/Components/Element/View.cs +++ b/src/RhinoInside.Revit.GH/Components/Element/View.cs @@ -55,7 +55,7 @@ public ElementPropertyView() Name = "View Specific", NickName = "S", Description = "Wheter element is view specific or not", - } + }, ParamRelevance.Primary ), new ParamDefinition ( @@ -63,8 +63,8 @@ public ElementPropertyView() { Name = "View", NickName = "V", - Description = "Element owner view", - } + Description = "The view that owns the Element.", + }, ParamRelevance.Primary ), }; @@ -73,8 +73,8 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (!Params.GetData(DA, "Element", out Types.GraphicalElement element, x => x.IsValid)) return; else DA.SetData("Element", element); - DA.SetData("View Specific", element.ViewSpecific); - DA.SetData("View", element.OwnerView); + Params.TrySetData(DA, "View Specific", () => element.ViewSpecific); + Params.TrySetData(DA, "View", () => element.OwnerView); } } }