diff --git a/docs/pages/_en/1.0/reference/release-notes.md b/docs/pages/_en/1.0/reference/release-notes.md index 51840ffc5..43f125d57 100644 --- a/docs/pages/_en/1.0/reference/release-notes.md +++ b/docs/pages/_en/1.0/reference/release-notes.md @@ -18,13 +18,18 @@ group: Deployment & Configs - Added 'Component Reference Plane' component. - Added 'Reference Annotations' component. - Improved 'Host Shape' performance. -- Now 'Query View Elements' filters out hidden UI categories. +- Now 'Query View Elements' filters out hidden UI _Categories_. - Added 'Is Visible UI' to 'Query Categories' and 'Category Identity'. - Added 'Query View Owned Elements' component. -- Renamed 'Query View Elements' to 'Query Visible Elements'. +- Renamed 'Query View Elements' -> 'Query Visible Elements'. - Added 'Query Title Blocks' component. - Added 'Query Viewports' component. -- Fixed 'Element Name' when used to Rename Subcategories in Multiple families at once. #974 +- Fixed 'Element Name' when used to rename _Subcategories_ in multiple families at once. + [#898](https://github.com/mcneel/rhino.inside-revit/issues/898) +- Fix on 'Query Categories' it should output ordered by id. +- Fix on 'Query Visible Elements' when a `` category is used. +- 'Element Subcategory' compoennt now works on `GenericForm` elements. + {% endcapture %} {% include ltr/release_header_next.html title="Upcoming Changes" note=rc_release_notes %} @@ -37,7 +42,7 @@ group: Deployment & Configs - Added {% include ltr/comp.html uuid='440b6beb' %} - Added {% include ltr/comp.html uuid='6388cfc0' %} -- Added {% include ltr/comp.html uuid='f9bc3f5e' %} +- Exposed {% include ltr/comp.html uuid='f9bc3f5e' %} - Includes all changes under 1.15RC releases listed below {% include ltr/release-header.html title="v1.15 RC2" version="v1.15.8571.17168" pre_release=true time="06/20/2023" %} @@ -116,7 +121,8 @@ group: Deployment & Configs - Moved Component Family related components to 'Component' panel. - Renamed 'Host Inserts' component to {% include ltr/comp.html uuid='70ccf7a6' %}. - Now {% include ltr/comp.html uuid='70ccf7a6' %} keep linked elements on linked documents. -- Fixd a bug on {% include ltr/comp.html uuid='ad88cf11' %} component 'Line Style' input when used on a Family document. #788 +- Fixd a bug on {% include ltr/comp.html uuid='ad88cf11' %} component 'Line Style' input when used on a Family document. + [#788](https://github.com/mcneel/rhino.inside-revit/issues/788) - Fixed a bug on previews when there are Groups on the canvas. - Now {% include ltr/comp.html uuid='c2b9b045' %} treats relative paths as temporary. - Now {% include ltr/comp.html uuid='c2b9b045' %} has a 'Path' output to allow chaining with 'Load Component Family'. @@ -168,10 +174,12 @@ group: Deployment & Configs {% include ltr/release-header.html title="v1.12 RC1" version="v1.12.8417.6530" pre_release=true time="01/17/2023" %} -- Fixed {% include ltr/comp.html uuid='01e86d7c' %} name is getting an unexpected integer added in creation. [#754](https://github.com/mcneel/rhino.inside-revit/issues/754) +- Fixed {% include ltr/comp.html uuid='01e86d7c' %} name is getting an unexpected integer added in creation. + [#754](https://github.com/mcneel/rhino.inside-revit/issues/754) - Added {% include ltr/comp.html uuid='e4e08f99' %} component. - Added {% include ltr/comp.html uuid='2922af4a' %} component. -- Added {% include ltr/comp.html uuid='b062c96e' %} component. [#753](https://github.com/mcneel/rhino.inside-revit/issues/753) +- Added {% include ltr/comp.html uuid='b062c96e' %} component. + [#753](https://github.com/mcneel/rhino.inside-revit/issues/753) {% include ltr/release-header.html title="v1.11" version="v1.11.8425.15605" time="01/10/2023" %} @@ -361,7 +369,8 @@ group: Deployment & Configs - Fixed structural framing creation on a family document. - Fixed curved Beams when in a vertical plane. - Fixed dimensioning components, when working with Detail Lines and Reference Planes. -- {% include ltr/comp.html uuid='8f1ee110' %} casting issue with enums [#613](https://github.com/mcneel/rhino.inside-revit/issues/613) +- {% include ltr/comp.html uuid='8f1ee110' %} casting issue with enums + [#613](https://github.com/mcneel/rhino.inside-revit/issues/613) {% include ltr/release-header.html title="v1.8 RC2" version="v1.8.8207.14855" pre_release=true time="06/21/2022" %} @@ -443,7 +452,8 @@ group: Deployment & Configs - Added support for Revit 2023 - Fixed conversion from {% include ltr/comp.html uuid='15ad6bf9' %} to Surface when slant angle is negative -- Fixed a bug on {% include ltr/comp.html uuid='0f251f87' %} [#507](https://github.com/mcneel/rhino.inside-revit/issues/507) +- Fixed a bug on {% include ltr/comp.html uuid='0f251f87' %} + [#507](https://github.com/mcneel/rhino.inside-revit/issues/507) - Updated Revit download link when loaded in an unsupported version {% include ltr/release-header.html title="v1.6 RC4" version="v1.6.8124.18574" pre_release=true time="04/05/2022" %} @@ -539,7 +549,8 @@ group: Deployment & Configs - Renamed 'Document Links' to {% include ltr/comp.html uuid='ebccfdd8-' %}. - Renamed 'Binding' to 'Scope' in parameter components. - Updated 'Element Dependents' to return original 'Elements' and also 'Referentials'. -- Fixed {% include ltr/comp.html uuid='b3bcbf5b-' %} and {% include ltr/comp.html uuid='8b85b1fb-' %}: Now both have an option _Expand Dependents_ in the context menu to extract dependent elements geometry. Outputs are grafted accordingly. Closes #509. +- Fixed {% include ltr/comp.html uuid='b3bcbf5b-' %} and {% include ltr/comp.html uuid='8b85b1fb-' %}: Now both have an option _Expand Dependents_ in the context menu to extract dependent elements geometry. Outputs are grafted accordingly. + [#509](https://github.com/mcneel/rhino.inside-revit/issues/509). - Updated some 'Query' component input parameters names to match Revit parameter name. {% include ltr/release-header.html title="v1.4 RC5" version="v1.4.8007.15883" pre_release=true time="12/07/2021" %} @@ -612,7 +623,8 @@ group: Deployment & Configs - Issues - - Fixed Non-C2-BREP edge conversion when knots are below tolerance. RE [#382](https://github.com/mcneel/rhino.inside-revit/issues/382). + - Fixed Non-C2-BREP edge conversion when knots are below tolerance. + [#382](https://github.com/mcneel/rhino.inside-revit/issues/382). - Minor Fixes and Improvements diff --git a/src/RhinoInside.Revit.GH/Components/Element/QueryElements.cs b/src/RhinoInside.Revit.GH/Components/Element/QueryElements.cs index 80ea1e5de..ffeca4425 100644 --- a/src/RhinoInside.Revit.GH/Components/Element/QueryElements.cs +++ b/src/RhinoInside.Revit.GH/Components/Element/QueryElements.cs @@ -187,8 +187,9 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (categories is object) { var ids = categories. - Where(x => x?.IsValid == true && (x.Document is null || x.Document.Equals(view.Document))). - Select(x => x.Id).ToArray(); + Where(x => x is object && (x.IsEmpty || x.IsValid) && (x.Document is null || x.Document.Equals(view.Document))). + Select(x => x.Id). + ToList(); elementCollector = elementCollector.WherePasses ( @@ -198,7 +199,10 @@ protected override void TrySolveInstance(IGH_DataAccess DA) else { // Default category filtering - var hiddenCategories = BuiltInCategoryExtension.GetHiddenInUIBuiltInCategories(view.Document) as ICollection; + var hiddenCategories = BuiltInCategoryExtension.GetHiddenInUIBuiltInCategories(view.Document). + Append(ARDB.BuiltInCategory.INVALID). // `ScheduleSheetInstance` Viewer has no Category, so we filter here + ToList(); + elementCollector = elementCollector.WherePasses ( new ARDB.ElementMulticategoryFilter(hiddenCategories, inverted: true) diff --git a/src/RhinoInside.Revit.GH/Components/ObjectStyles/QueryCategories.cs b/src/RhinoInside.Revit.GH/Components/ObjectStyles/QueryCategories.cs index 3e406fad2..163d92d74 100644 --- a/src/RhinoInside.Revit.GH/Components/ObjectStyles/QueryCategories.cs +++ b/src/RhinoInside.Revit.GH/Components/ObjectStyles/QueryCategories.cs @@ -58,7 +58,7 @@ public QueryCategories() : base ParamDefinition.Create>("Type", "T", "Category type", ARDB.CategoryType.Model, optional: true, relevance: ParamRelevance.Primary), ParamDefinition.Create("Parent", "P", "Parent category", optional: true, relevance: ParamRelevance.Occasional), ParamDefinition.Create("Name", "N", "Category name", optional: true), - ParamDefinition.Create("Is Subcategory", "ISC", "Is subcategory", defaultValue: false, GH_ParamAccess.item, optional: true), + ParamDefinition.Create("Is Subcategory", "ISC", "Is subcategory", defaultValue: false, optional: true), ParamDefinition.Create("Is Visible UI", "VUI", "Category is exposed in UI", defaultValue: true, optional: true, relevance: ParamRelevance.Primary), ParamDefinition.Create("Allows Subcategories", "ASC", "Category allows subcategories to be added", optional: true, relevance: ParamRelevance.Secondary), ParamDefinition.Create("Allows Parameters", "AP", "Category allows bound parameters", optional: true, relevance: ParamRelevance.Secondary), @@ -126,7 +126,8 @@ protected override void TrySolveInstance(IGH_DataAccess DA) "Categories", categories. Select(x => new Types.Category(x)). - TakeWhileIsNotEscapeKeyDown(this) + TakeWhileIsNotEscapeKeyDown(this). + OrderBy(x => x.Id.ToValue()) ); } } diff --git a/src/RhinoInside.Revit.GH/Components/Views/QueryViewElements.cs b/src/RhinoInside.Revit.GH/Components/Views/QueryViewElements.cs index 12e5d2417..67b1c5513 100644 --- a/src/RhinoInside.Revit.GH/Components/Views/QueryViewElements.cs +++ b/src/RhinoInside.Revit.GH/Components/Views/QueryViewElements.cs @@ -55,8 +55,9 @@ protected override void TrySolveInstance(IGH_DataAccess DA) if (categories is object) { var ids = categories. - Where(x => x?.IsValid == true && (x.Document is null || x.Document.Equals(view.Document))). - Select(x => x.Id).ToArray(); + Where(x => x is object && (x.IsEmpty || x.IsValid) && (x.Document is null || x.Document.Equals(view.Document))). + Select(x => x.Id). + ToList(); elementCollector = elementCollector.WherePasses ( @@ -66,7 +67,10 @@ protected override void TrySolveInstance(IGH_DataAccess DA) else { // Default category filtering - var hiddenCategories = BuiltInCategoryExtension.GetHiddenInUIBuiltInCategories(view.Document) as ICollection; + var hiddenCategories = BuiltInCategoryExtension.GetHiddenInUIBuiltInCategories(view.Document). + Append(ARDB.BuiltInCategory.INVALID). // `ScheduleSheetInstance` Viewer has no Category, so we filter here + ToList(); + elementCollector = elementCollector.WherePasses ( new ARDB.ElementMulticategoryFilter(hiddenCategories, inverted: true) diff --git a/src/RhinoInside.Revit.GH/Parameters/Elevation.cs b/src/RhinoInside.Revit.GH/Parameters/Elevation.cs index 1d64b3e78..6719f993d 100644 --- a/src/RhinoInside.Revit.GH/Parameters/Elevation.cs +++ b/src/RhinoInside.Revit.GH/Parameters/Elevation.cs @@ -489,7 +489,7 @@ public ProjectElevation() : base } } -namespace RhinoInside.Revit.GH.Components.Input +namespace RhinoInside.Revit.GH.Components.Site { [ComponentVersion(introduced: "1.0", updated: "1.14")] public class ConstructProjectElevation : ZuiComponent diff --git a/src/RhinoInside.Revit.GH/Parameters/LevelConstraint.cs b/src/RhinoInside.Revit.GH/Parameters/LevelConstraint.cs index fa00c0ee9..1a6a91fd1 100644 --- a/src/RhinoInside.Revit.GH/Parameters/LevelConstraint.cs +++ b/src/RhinoInside.Revit.GH/Parameters/LevelConstraint.cs @@ -160,9 +160,9 @@ protected override void TrySolveInstance(IGH_DataAccess DA) } } - Params.TrySetData(DA, "Elevation", () => level is object ? new Types.LevelConstraint(level, offset ?? 0.0) : default); + Params.TrySetData(DA, "Elevation", () => level is object || offset is object ? new Types.LevelConstraint(level ?? new Types.Level(), offset ?? 0.0) : null); Params.TrySetData(DA, "Level", () => level); - Params.TrySetData(DA, "Offset", () => offset); + Params.TrySetData(DA, "Offset", () => offset ?? (level is null ? default(double?) : 0.0)); } } } diff --git a/src/RhinoInside.Revit.GH/Types/CombinableElement.cs b/src/RhinoInside.Revit.GH/Types/CombinableElement.cs index 3ce94b726..265e565c9 100644 --- a/src/RhinoInside.Revit.GH/Types/CombinableElement.cs +++ b/src/RhinoInside.Revit.GH/Types/CombinableElement.cs @@ -1,36 +1,74 @@ using System; -using System.Linq; using Grasshopper.Kernel.Types; using ARDB = Autodesk.Revit.DB; namespace RhinoInside.Revit.GH.Types { - [Kernel.Attributes.Name("Form")] - public class CombinableElement : GeometricElement, IGH_InstanceElement + [Kernel.Attributes.Name("Combinable")] + public class CombinableElement : GeometricElement { protected override Type ValueType => typeof(ARDB.CombinableElement); public new ARDB.CombinableElement Value => base.Value as ARDB.CombinableElement; public CombinableElement() { } public CombinableElement(ARDB.CombinableElement element) : base(element) { } + } + + [Kernel.Attributes.Name("Combination")] + public class GeomCombination : CombinableElement + { + protected override Type ValueType => typeof(ARDB.GeomCombination); + public new ARDB.GeomCombination Value => base.Value as ARDB.GeomCombination; + + public GeomCombination() { } + public GeomCombination(ARDB.GeomCombination element) : base(element) { } + } + + [Kernel.Attributes.Name("Form")] + public class GenericForm : CombinableElement + { + protected override Type ValueType => typeof(ARDB.GenericForm); + public new ARDB.GenericForm Value => base.Value as ARDB.GenericForm; + + public GenericForm() { } + public GenericForm(ARDB.GenericForm element) : base(element) { } #region Category - public override Category Category + public override Category Subcategory { + get + { + var paramId = ARDB.BuiltInParameter.FAMILY_ELEM_SUBCATEGORY; + if (paramId != ARDB.BuiltInParameter.INVALID && Value is ARDB.Element element) + { + using (var parameter = element.get_Parameter(paramId)) + { + if (parameter?.AsElementId() is ARDB.ElementId categoryId) + { + var category = new Category(Document, categoryId); + return category.APIObject?.Parent is null ? new Category() : category; + } + } + } + + return default; + } + set { + var paramId = ARDB.BuiltInParameter.FAMILY_ELEM_SUBCATEGORY; if (value is object && Value is ARDB.Element element) { - using (var parameter = element.get_Parameter(ARDB.BuiltInParameter.FAMILY_ELEM_SUBCATEGORY)) + using (var parameter = element.get_Parameter(paramId)) { if (parameter is null) { if (value.Id != ARDB.ElementId.InvalidElementId) - throw new Exceptions.RuntimeErrorException($"{((IGH_Goo) this).TypeName} '{DisplayName}' does not support assignment of a Category."); + throw new Exceptions.RuntimeErrorException($"{((IGH_Goo) this).TypeName} '{DisplayName}' does not support assignment of a Subcategory."); } else { - AssertValidDocument(value, nameof(Category)); + AssertValidDocument(value, nameof(Subcategory)); parameter.Update(value); } } diff --git a/src/RhinoInside.Revit.GH/Types/DocumentObject.cs b/src/RhinoInside.Revit.GH/Types/DocumentObject.cs index 13f253dda..7a81b1d9c 100644 --- a/src/RhinoInside.Revit.GH/Types/DocumentObject.cs +++ b/src/RhinoInside.Revit.GH/Types/DocumentObject.cs @@ -205,6 +205,8 @@ public bool Equals(ReferenceObject other) => other is object && #endregion #region DocumentObject + public bool IsEmpty => !IsReferencedData; + public override object Value { get diff --git a/src/RhinoInside.Revit.GH/Types/Element.Activator.cs b/src/RhinoInside.Revit.GH/Types/Element.Activator.cs index 80326bebc..201bb4045 100644 --- a/src/RhinoInside.Revit.GH/Types/Element.Activator.cs +++ b/src/RhinoInside.Revit.GH/Types/Element.Activator.cs @@ -268,6 +268,7 @@ public static Element FromReference(ARDB.Document doc, ARDB.Reference reference) { typeof(ARDB.ViewFamilyType), (element)=> new ViewFamilyType (element as ARDB.ViewFamilyType) }, { typeof(ARDB.View), (element)=> new View (element as ARDB.View) }, { typeof(ARDB.Viewport), (element)=> new Viewport (element as ARDB.Viewport) }, + { typeof(ARDB.ScheduleSheetInstance), (element)=> new ScheduleSheetInstance (element as ARDB.ScheduleSheetInstance)}, { typeof(ARDB.ViewSheet), (element)=> new ViewSheet (element as ARDB.ViewSheet) }, { typeof(ARDB.View3D), (element)=> new View3D (element as ARDB.View3D) }, { typeof(ARDB.ViewPlan), (element)=> new ViewPlan (element as ARDB.ViewPlan) }, @@ -289,6 +290,8 @@ public static Element FromReference(ARDB.Document doc, ARDB.Reference reference) { typeof(ARDB.SketchPlane), (element)=> new SketchPlane (element as ARDB.SketchPlane) }, { typeof(ARDB.CurveElement), (element)=> new CurveElement (element as ARDB.CurveElement) }, { 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.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/Element.cs b/src/RhinoInside.Revit.GH/Types/Element.cs index 1ebed3f02..cd96b8179 100755 --- a/src/RhinoInside.Revit.GH/Types/Element.cs +++ b/src/RhinoInside.Revit.GH/Types/Element.cs @@ -466,8 +466,6 @@ Value.Category is ARDB.Category category ? Category.FromCategory(category) : new Category() : default; - - set => throw new Exceptions.RuntimeErrorException($"{((IGH_Goo) this).TypeName} '{DisplayName}' does not support assignment of a Category."); } public virtual ElementType Type diff --git a/src/RhinoInside.Revit.GH/Types/GraphicalElement.cs b/src/RhinoInside.Revit.GH/Types/GraphicalElement.cs index ded09bc18..b3221b17e 100644 --- a/src/RhinoInside.Revit.GH/Types/GraphicalElement.cs +++ b/src/RhinoInside.Revit.GH/Types/GraphicalElement.cs @@ -397,7 +397,7 @@ public override bool CastTo(out Q target) public virtual Category Subcategory { get => default; - set => throw new Exceptions.RuntimeErrorException($"{((IGH_Goo) this).TypeName} '{DisplayName}' does not support assignment of a Subcategory."); + set { if (value is object) throw new Exceptions.RuntimeErrorException($"{((IGH_Goo) this).TypeName} '{DisplayName}' does not support assignment of a Subcategory."); } } public virtual ARDB.ElementId LevelId => Value?.LevelId; diff --git a/src/RhinoInside.Revit.GH/Types/InstanceElement.cs b/src/RhinoInside.Revit.GH/Types/InstanceElement.cs index 095382b12..82155c4d8 100644 --- a/src/RhinoInside.Revit.GH/Types/InstanceElement.cs +++ b/src/RhinoInside.Revit.GH/Types/InstanceElement.cs @@ -28,6 +28,11 @@ public InstanceElement(ARDB.Element element) : base(element) { } } #region IHostElementAccess + GraphicalElement IHostElementAccess.HostElement => Value is ARDB.Element element ? + element.ViewSpecific ? OwnerView?.Viewer : + HostElement : + default; + public virtual GraphicalElement HostElement => Value is ARDB.Element element ? GetElement(element.LevelId) : default; diff --git a/src/RhinoInside.Revit.GH/Types/ObjectStyles/Category.cs b/src/RhinoInside.Revit.GH/Types/ObjectStyles/Category.cs index ebf37c54b..69176d1a1 100644 --- a/src/RhinoInside.Revit.GH/Types/ObjectStyles/Category.cs +++ b/src/RhinoInside.Revit.GH/Types/ObjectStyles/Category.cs @@ -470,7 +470,12 @@ public override string Nomen public Category Parent => _IsSubcategory == false ? null : FromCategory(APIObject?.Parent); - public IEnumerable SubCategories => APIObject?.SubCategories?.Cast().Select(FromCategory); + public IEnumerable SubCategories => APIObject?. + SubCategories?. + Cast(). + Where(x => !x.AllowsBoundParameters). + OrderBy(x => x.Id.ToValue()). + Select(FromCategory); bool? _IsTagCategory; public bool? IsTagCategory => _IsTagCategory ?? (_IsTagCategory = APIObject?.IsTagCategory); diff --git a/src/RhinoInside.Revit.GH/Types/Views/Viewport.cs b/src/RhinoInside.Revit.GH/Types/Views/Viewport.cs index 3a9306316..65398ee31 100644 --- a/src/RhinoInside.Revit.GH/Types/Views/Viewport.cs +++ b/src/RhinoInside.Revit.GH/Types/Views/Viewport.cs @@ -9,7 +9,8 @@ namespace RhinoInside.Revit.GH.Types using Convert.Geometry; [Kernel.Attributes.Name("Viewport")] - public class Viewport : GraphicalElement + public class Viewport : GraphicalElement, + IHostElementAccess { protected override Type ValueType => typeof(ARDB.Viewport); public new ARDB.Viewport Value => base.Value as ARDB.Viewport; @@ -222,9 +223,175 @@ protected override void DrawViewportMeshes(GH_PreviewMeshArgs args) } #endregion + #region IHostElementAccess + GraphicalElement IHostElementAccess.HostElement => Sheet?.Viewer; + #endregion + #region Properties public View View => View.FromElementId(Document, Value?.ViewId) as View; public ViewSheet Sheet => ViewSheet.FromElementId(Document, Value?.SheetId) as ViewSheet; #endregion } + + [Kernel.Attributes.Name("Schedule Graphics")] + public class ScheduleSheetInstance : GraphicalElement, + IHostElementAccess + { + protected override Type ValueType => typeof(ARDB.ScheduleSheetInstance); + public new ARDB.ScheduleSheetInstance Value => base.Value as ARDB.ScheduleSheetInstance; + + public ScheduleSheetInstance() { } + public ScheduleSheetInstance(ARDB.ScheduleSheetInstance element) : base(element) { } + + public override bool CastTo(out Q target) + { + if (base.CastTo(out target)) + return true; + + if (typeof(ViewSheet).IsAssignableFrom(typeof(Q))) + { + target = (Q) (object) Sheet; + return true; + } + + if (typeof(Q).IsAssignableFrom(typeof(View))) + { + target = (Q) (object) View; + return true; + } + + if (typeof(Q).IsAssignableFrom(typeof(GH_Material))) + { + target = (Q) (object) new GH_Material { Value = View.ToDisplayMaterial() }; + return true; + } + + return false; + } + + public override Plane Location + { + get + { + if (Value is ARDB.ScheduleSheetInstance viewport && viewport.OwnerViewId != ARDB.ElementId.InvalidElementId) + { + var boxCenter = base.Location.Origin; + boxCenter.Z = 0.0; + + switch (viewport.Rotation) + { + case ARDB.ViewportRotation.None: return new Plane(boxCenter, Vector3d.XAxis, Vector3d.YAxis); + case ARDB.ViewportRotation.Clockwise: return new Plane(boxCenter, -Vector3d.YAxis, Vector3d.XAxis); + case ARDB.ViewportRotation.Counterclockwise: return new Plane(boxCenter, Vector3d.YAxis, -Vector3d.XAxis); + } + } + + return NaN.Plane; + } + } + + public override Surface Surface + { + get + { + var surface = default(PlaneSurface); + var boxOutline = BoundingBox; + if (boxOutline.IsValid) + { + var padding = 0.01 * Revit.ModelUnits; + var location = Location; + switch (Value.Rotation) + { + case ARDB.ViewportRotation.None: + { + var outlineU = new Interval(boxOutline.Min.X - location.Origin.X + padding, boxOutline.Max.X - location.Origin.X - padding); + var outlineV = new Interval(boxOutline.Min.Y - location.Origin.Y + padding, boxOutline.Max.Y - location.Origin.Y - padding); + surface = new PlaneSurface(location, outlineU, outlineV); + break; + } + + case ARDB.ViewportRotation.Clockwise: + { + var outlineU = new Interval(boxOutline.Min.Y - location.Origin.Y + padding, boxOutline.Max.Y - location.Origin.Y - padding); + var outlineV = new Interval(boxOutline.Min.X - location.Origin.X + padding, boxOutline.Max.X - location.Origin.X - padding); + surface = new PlaneSurface(location, outlineU, outlineV); + break; + } + + case ARDB.ViewportRotation.Counterclockwise: + { + var outlineU = new Interval(boxOutline.Min.Y - location.Origin.Y + padding, boxOutline.Max.Y - location.Origin.Y - padding); + var outlineV = new Interval(boxOutline.Min.X - location.Origin.X + padding, boxOutline.Max.X - location.Origin.X - padding); + surface = new PlaneSurface(location, outlineU, outlineV); + break; + } + } + + var viewOutline = View.GetOutline(Rhino.DocObjects.ActiveSpace.ModelSpace); + surface.SetDomain(0, viewOutline.U); + surface.SetDomain(1, viewOutline.V); + } + + return surface; + } + } + + Mesh _Mesh; + public override Mesh Mesh => _Mesh ?? (_Mesh = Mesh.CreateFromSurface(Surface)); + + #region IGH_PreviewData + protected override void SubInvalidateGraphics() + { + _Mesh = default; + + base.SubInvalidateGraphics(); + } + + protected override void DrawViewportWires(GH_PreviewWireArgs args) + { + if (Value is ARDB.ScheduleSheetInstance viewport && viewport.OwnerViewId != ARDB.ElementId.InvalidElementId) + { + using (var boxOutline = BoundingBox.ToOutline()) + { + if (!boxOutline.IsEmpty) + { + var points = new Point3d[] + { + boxOutline.MinimumPoint.ToPoint3d(), + Point3d.Origin, + boxOutline.MaximumPoint.ToPoint3d(), + Point3d.Origin + }; + + points[0] = new Point3d(points[0].X, points[0].Y, 0.0); + points[1] = new Point3d(points[2].X, points[0].Y, 0.0); + points[2] = new Point3d(points[2].X, points[2].Y, 0.0); + points[3] = new Point3d(points[0].X, points[2].Y, 0.0); + + args.Pipeline.DrawPatternedPolyline(points, args.Color, 0x00003333, args.Thickness, close: true); + } + } + + var view = Document.GetElement(viewport.ScheduleId) as ARDB.View; + if (view is ARDB.ImageView) return; + } + else base.DrawViewportWires(args); + } + + protected override void DrawViewportMeshes(GH_PreviewMeshArgs args) + { + if (Mesh is Mesh mesh) + args.Pipeline.DrawMeshShaded(mesh, args.Material); + } + #endregion + + #region IHostElementAccess + GraphicalElement IHostElementAccess.HostElement => Sheet?.Viewer; + #endregion + + #region Properties + public View View => View.FromElementId(Document, Value?.ScheduleId) as View; + public ViewSheet Sheet => ViewSheet.FromElementId(Document, Value?.OwnerViewId) as ViewSheet; + #endregion + } }