{"id":17335127,"url":"https://github.com/nice3point/revitextensions","last_synced_at":"2025-04-06T03:08:41.066Z","repository":{"id":41286974,"uuid":"442216223","full_name":"Nice3point/RevitExtensions","owner":"Nice3point","description":"Extensions for Revit plugin development","archived":false,"fork":false,"pushed_at":"2025-03-03T12:56:09.000Z","size":370,"stargazers_count":107,"open_issues_count":0,"forks_count":22,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-30T02:06:19.039Z","etag":null,"topics":["extensions","revit"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Nice3point.png","metadata":{"files":{"readme":"Readme.md","changelog":"Changelog.md","contributing":"Contributing.md","funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-27T16:42:29.000Z","updated_at":"2025-03-06T06:15:04.000Z","dependencies_parsed_at":"2024-03-09T13:40:46.938Z","dependency_job_id":"42e75157-d01d-4b8f-9764-6a82dc2decf8","html_url":"https://github.com/Nice3point/RevitExtensions","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FRevitExtensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FRevitExtensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FRevitExtensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FRevitExtensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nice3point","download_url":"https://codeload.github.com/Nice3point/RevitExtensions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427006,"owners_count":20937201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["extensions","revit"],"created_at":"2024-10-15T15:08:20.060Z","updated_at":"2025-04-06T03:08:41.057Z","avatar_url":"https://github.com/Nice3point.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cpicture\u003e\n        \u003csource media=\"(prefers-color-scheme: dark)\" width=\"750\" srcset=\"https://github.com/Nice3point/RevitExtensions/assets/20504884/d605eb83-74a7-4a47-9db8-cb0daced374e\"\u003e\n        \u003cimg alt=\"RevitLookup\" width=\"750\" src=\"https://github.com/Nice3point/RevitExtensions/assets/20504884/a1772d7d-38d4-4a9b-9985-1d83b8cbea8d\"\u003e\n    \u003c/picture\u003e\n\u003c/p\u003e\n\n## Improve your experience with Revit API\n\n[![Nuget](https://img.shields.io/nuget/vpre/Nice3point.Revit.Extensions?style=for-the-badge)](https://www.nuget.org/packages/Nice3point.Revit.Extensions)\n[![Downloads](https://img.shields.io/nuget/dt/Nice3point.Revit.Extensions?style=for-the-badge)](https://www.nuget.org/packages/Nice3point.Revit.Extensions)\n[![Last Commit](https://img.shields.io/github/last-commit/Nice3point/RevitExtensions/develop?style=for-the-badge)](https://github.com/Nice3point/RevitExtensions/commits/develop)\n\nExtensions make working with the Revit API much easier and more intuitive. They add helpful methods that make your code cleaner, easier to understand, and simpler to maintain. Generics, nullable, everything here.\n\nInstead of writing complex utility functions, you can use these extensions to write code in a natural, fluent way that focuses on what you actually want to do:\n\n```csharp\nnew ElementId(123469)\n    .ToElement\u003cDoor\u003e()\n    .Mirror()\n    .FindParameter(\"Height\")\n    .AsDouble()\n    .ToMillimeters()\n    .Round()\n```\n\n## Installation\n\nYou can install the Extensions as a [NuGet package](https://www.nuget.org/packages/Nice3point.Revit.Extensions).\n\nThe packages are compiled for specific versions of Revit. To support different versions of libraries in one project, use the `RevitVersion` property:\n\n```xml\n\u003cPackageReference Include=\"Nice3point.Revit.Extensions\" Version=\"$(RevitVersion).*\"/\u003e\n```\n\nPackage included by default in [Revit Templates](https://github.com/Nice3point/RevitTemplates).\n\n## Table of contents\n\n\u003c!-- TOC --\u003e\n  * [Element extensions](#element-extensions)\n    * [Element transform extensions](#element-transform-extensions)\n    * [Element association extensions](#element-association-extensions)\n    * [Element validation extensions](#element-validation-extensions)\n    * [Element worksharing extensions](#element-worksharing-extensions)\n    * [Element schema extensions](#element-schema-extensions)\n  * [ElementId extensions](#elementid-extensions)\n    * [ElementId transform extensions](#elementid-transform-extensions)\n  * [Application extensions](#application-extensions)\n    * [Ribbon Extensions](#ribbon-extensions)\n    * [ContextMenu Extensions](#contextmenu-extensions)\n  * [Document extensions](#document-extensions)\n    * [Document managers extensions](#document-managers-extensions)\n  * [Geometry extensions](#geometry-extensions)\n    * [Element geometry extensions](#element-geometry-extensions)\n  * [Parameters extensions](#parameters-extensions)\n    * [Document global parameters extensions](#document-global-parameters-extensions)\n  * [FilteredElementCollector extensions](#filteredelementcollector-extensions)\n  * [ForgeTypeId extensions](#forgetypeid-extensions)\n  * [Unit Extensions](#unit-extensions)\n  * [Label Extensions](#label-extensions)\n  * [Color extensions](#color-extensions)\n  * [Family extensions](#family-extensions)\n  * [HostObject extensions](#hostobject-extensions)\n  * [Plumbing extensions](#plumbing-extensions)\n  * [Solid extensions](#solid-extensions)\n    * [Element solid cut extensions](#element-solid-cut-extensions)\n  * [View extensions](#view-extensions)\n    * [View managers extensions](#view-managers-extensions)\n  * [Imperial Extensions](#imperial-extensions)\n  * [System Extensions](#system-extensions)\n\n## Element extensions\n\n**FindParameter** extension finds a parameter in the instance or symbol by identifier.\nFor instances that do not have such a parameter, this method will find and return it at the element type.\nThis method combines all API methods for getting a parameter into one, such as `get_Parameter`, `LookupParameter`, `GetParameter`.\n\n```csharp\nvar parameter = element.FindParameter(ParameterTypeId.AllModelUrl);\nvar parameter = element.FindParameter(BuiltInParameter.ALL_MODEL_URL);\nvar parameter = element.FindParameter(\"URL\");\n```\n\n### Element transform extensions\n\n**Copy** extension copies an element and places the copy at a location indicated by a given transformation.\n\n```csharp\nelement.Copy(1, 1, 0);\nelement.Copy(new XYZ(1, 1, 0));\n```\n\n**Mirror** extension creates a mirrored copy of an element about a given plane.\n\n```csharp\nelement.Mirror(plane);\n```\n\n**Move** extension moves the element by the specified vector.\n\n```csharp\nelement.Move(1, 1, 0);\nelement.Move(new XYZ(1, 1, 0));\n```\n\n**Rotate** extension rotates an element about the given axis and angle.\n\n```csharp\nelement.Rotate(axis, angle);\n```\n\n**CanBeMirrored** extension determines whether an element can be mirrored.\n\n```csharp\nvar canMirror = element.CanBeMirrored();\n```\n\n### Element association extensions\n \n**IsAnalyticalElement** extension returns true if the element is an analytical element.\n\n```csharp\nvar isAnalytical = element.IsAnalyticalElement();\n```\n\n**IsPhysicalElement** extension returns true if the element is a physical element.\n\n```csharp\nvar isPhysical = element.IsPhysicalElement();\n```\n\n### Element validation extensions\n \n**CanDeleteElement** extension indicates whether an element can be deleted.\n\n```csharp\nvar canDelete = element.CanDeleteElement();\n```\n\n### Element worksharing extensions\n \n**GetCheckoutStatus** extension gets the ownership status of an element.\n\n```csharp\nvar status = element.GetCheckoutStatus();\n```\n\n**GetCheckoutStatus** extension gets the ownership status and outputs the owner of an element.\n\n```csharp\nvar status = element.GetCheckoutStatus(out var owner);\n```\n\n**GetCheckoutStatus** extension gets worksharing information about an element to display in an in-canvas tooltip.\n\n```csharp\nvar info = element.GetWorksharingTooltipInfo();\n```\n\n**GetModelUpdatesStatus** extension gets the status of a single element in the central model.\n\n```csharp\nvar status = element.GetModelUpdatesStatus();\n```\n\n### Element schema extensions\n\n**SaveEntity** extension stores data in the element. Existing data is overwritten.\n\n```csharp\ndocument.ProjectInformation.SaveEntity(schema, \"data\", \"schemaField\");\ndoor.SaveEntity(schema, \"white\", \"doorColorField\");\n```\n\n**LoadEntity** extension retrieves the value stored in the schema from the element.\n\n```csharp\nvar data = document.ProjectInformation.LoadEntity\u003cstring\u003e(schema, \"schemaField\");\nvar color = door.LoadEntity\u003cstring\u003e(schema, \"doorColorField\");\n```\n\n## ElementId extensions\n\n**ToElement** extension retrieves the element associated with the specified ElementId.\n\n```csharp\nElement element = wallId.ToElement(document);\nWall wall = wallId.ToElement\u003cWall\u003e(document);\n```\n\n**ToElements** extension retrieves a collection of elements associated with the specified ElementIds.\n\n```csharp\nIList\u003cElement\u003e elements = wallIds.ToElements(document);\nIList\u003cWall\u003e walls = wallIds.ToElements\u003cWall\u003e(document);\n```\n\nTo improve database access performance, it is not guaranteed that the elements will be retrieved in the original order.\nIf you need the same order, use the `ToOrderedElements` extension.\n\n**ToOrderedElements** extension retrieves the elements associated with the specified ElementIds in their original order.\n\n```csharp\nIList\u003cElement\u003e elements = wallIds.ToOrderedElements(document);\nIList\u003cWall\u003e walls = wallIds.ToOrderedElements\u003cWall\u003e(document);\n```\n\nThe elements will be retrieved in the same order as the original ElementIds collection.\n\n**AreEquals** extension checks if an ID matches BuiltInCategory or BuiltInParameter.\n\n```csharp\ncategoryId.AreEquals(BuiltInCategory.OST_Walls);\nparameterId.AreEquals(BuiltInParameter.WALL_BOTTOM_IS_ATTACHED);\n```\n\n### ElementId transform extensions\n\n**CanMirrorElements** extension determines whether elements can be mirrored.\n\n```csharp\nvar canMirror = elementIds.CanMirrorElements(document);\n```\n\n**MirrorElements** extension mirrors a set of elements about a given plane.\n\n```csharp\nvar elements = elementIds.MirrorElements(document, plane, mirrorCopies: true);\n```\n\n**MoveElements** extension moves a set of elements by a given transformation.\n\n```csharp\nelementIds.MoveElements(document, new XYZ(1, 1, 1));\n```\n\n**RotateElements** extension rotates a set of elements about the given axis and angle.\n\n```csharp\nelementIds.RotateElements(document, axis, angle: 3.14);\n```\n\n**CopyElements** extension copies a set of elements from source view to destination view.\n\n```csharp\nvar copy = elementIds.CopyElements(source, destination);\nvar copy = elementIds.CopyElements(source, destination, transform, options);\n```\n\n**CopyElements** extension copies a set of elements and places the copies at a location indicated by a given translation.\n\n```csharp\nvar copy = elementIds.CopyElements(document, new XYZ(1, 1, 1));\n```\n\n## Application extensions\n### Ribbon Extensions\n\n[Revit API Ribbon controls Guidelines](https://help.autodesk.com/view/RVT/2025/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Introduction_Add_In_Integration_Ribbon_Panels_and_Controls_html)\n\n**CreatePanel** extension creates or retrieves an existing panel in the \"Add-ins\" tab of the Revit ribbon.\n\nIf a panel with the specified name already exists within the tab, it will return that panel; otherwise, a new one will be created.\n\nAdding a panel also supports built-in tabs. To add a panel to the built-in Revit tab, specify the panel **ID** or **Name** as the `tabName` parameter\n\n```csharp\nvar panel = application.CreatePanel(\"Panel name\");\nvar panel = application.CreatePanel(\"Panel name\", \"Tab name\");\n```\n\n![regularControls](https://github.com/user-attachments/assets/c5d202e0-0c16-4c84-b183-b09582676b05)\n\n**RemovePanel** extension removes RibbonPanel from the Revit ribbon.\n\n```csharp\nvar textBox = panel.RemovePanel();\n```\n\n**AddPushButton** extension adds a PushButton to the ribbon.\n\n```csharp\nvar button = panel.AddPushButton\u003cCommand\u003e(\"Button text\");\nvar button = pullDownButton.AddPushButton\u003cCommand\u003e(\"Button text\");\n```\n\n**AddPullDownButton** extension adds a PullDownButton to the ribbon.\n\n```csharp\nvar button = panel.AddPullDownButton(\"Button text\");\n```\n\n**AddSplitButton** extension adds a SplitButton to the ribbon.\n\n```csharp\nvar button = panel.AddSplitButton(\"Button text\");\n```\n\n**AddRadioButtonGroup** extension adds a RadioButtonGroup to the ribbon.\n\n```csharp\nvar radioGroup = panel.AddRadioButtonGroup();\n```\n\n**AddComboBox** extension adds a ComboBox to the ribbon.\n\n```csharp\nvar comboBox = panel.AddComboBox();\n```\n\n**AddTextBox** extension adds a TextBox to the ribbon.\n\n```csharp\nvar textBox = panel.AddTextBox();\n```\n\n**SetBackground** extension sets the panel background color.\n\n```csharp\npanel.SetBackground(\"Red\");\npanel.SetBackground(\"#FF0000\");\npanel.SetBackground(\"#AAFF0000\");\npanel.SetBackground(Colors.Red);\npanel.SetBackground(Brushes.Red);\npanel.SetBackground(new LinearGradientBrush(\n[\n    new GradientStop(Colors.White, 0),\n    new GradientStop(Colors.Red, 1)\n], 45));\n```\n\n**SetTitleBarBackground** extension sets the panel title bar background color.\n\n```csharp\npanel.SetTitleBarBackground(\"Blue\");\npanel.SetTitleBarBackground(\"#0000FF\");\npanel.SetTitleBarBackground(\"#AA0000FF\");\npanel.SetTitleBarBackground(Colors.Blue);\npanel.SetTitleBarBackground(Brushes.Blue);\npanel.SetTitleBarBackground(new LinearGradientBrush(\n[\n    new GradientStop(Colors.White, 0),\n    new GradientStop(Colors.Blue, 1)\n], 45));\n```\n\n**SetSlideOutPanelBackground** extension sets the slide-out panel background color for the target panel.\n\n```csharp\npanel.SetSlideOutBackground(\"Green\");\npanel.SetSlideOutBackground(\"#00FF00\");\npanel.SetSlideOutBackground(\"#AA00FF00\");\npanel.SetSlideOutBackground(Colors.Green);\npanel.SetSlideOutBackground(Brushes.Green);\npanel.SetSlideOutBackground(new LinearGradientBrush(\n[\n    new GradientStop(Colors.White, 0),\n    new GradientStop(Colors.Green, 1)\n], 45));\n```\n\n**AddStackPanel** extension adds a vertical stack panel to the Ribbon panel.\n\n```csharp\nvar stackPanel = panel.AddStackPanel();\n```\n\nBy default, the StackPanel accommodates one to three elements vertically. \nIf the added items exceed the maximum threshold, they will be automatically added to a new column.\n\nThese 5 items will create 2 vertical panels, one will contain 3 items and the other 2 items:\n\n```csharp\nvar stackPanel = panel.AddStackPanel();\nstackPanel.AddPushButton\u003cStartupCommand\u003e(\"Execute\");\nstackPanel.AddPullDownButton(\"Execute\");\nstackPanel.AddSplitButton(\"Execute\");\nstackPanel.AddLabel(\"Items:\");\nstackPanel.AddComboBox();\nstackPanel.AddTextBox();\n```\n\n![verticalStack](https://github.com/user-attachments/assets/3cef1e86-89a3-4f9c-8a06-b7661c6f428f)\n\n**SetImage** extension adds an image to the RibbonButton.\n\n```csharp\nbutton.SetImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon16.png\");\nbutton.SetImage(\"https://example.com/RibbonIcon16.png\");\nbutton.SetImage(\"C:/Pictures/RibbonIcon16.png\");\n```\n\n**SetLargeImage** extension adds a large image to the RibbonButton.\n\n```csharp\nbutton.SetLargeImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon32.png\");\nbutton.SetLargeImage(\"https://example.com/RibbonIcon32.png\");\nbutton.SetLargeImage(\"C:/Pictures/RibbonIcon32.png\");\n```\n\nStarting with Revit 2024 **SetImage** and **SetLargeImage** extensions support Light and Dark UI themes.\n\nWhen the provided image name contains \"light\" or \"dark\" (case-insensitive), the extensions automatically modify the URI to match the current UI theme. \nFor example:\n\n```csharp\nbutton.SetImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon16-Light.png\");\nbutton.SetImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon16_light.png\");\n\n// in the Dark Revit theme will be converted to:\nbutton.SetImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon16-Dark.png\");\nbutton.SetImage(\"/RevitAddIn;component/Resources/Icons/RibbonIcon16_dark.png\");\n```\n\n**SetToolTip** extension sets the tooltip text for the RibbonItem.\n\n```csharp\nbutton.SetToolTip(\"Tooltip);\n```\n\n**SetLongDescription** extension sets the extended tooltip description for the RibbonItem.\n\n```csharp\nbutton.SetLongDescription(\"Description);\n```\n\n**SetAvailabilityController** extension specifies the class that decides the availability of PushButton.\n\n```csharp\npushButton.SetAvailabilityController\u003cCommandController\u003e();\n```\n\n**AddShortcuts** extension adds keyboard shortcuts to the PushButton.\n\n```csharp\npushButton.AddShortcuts(\"RE\");\npushButton.AddShortcuts(\"RE#NP\");\npushButton.AddShortcuts(\"RE\", \"NP\");\npushButton.AddShortcuts([\"RE\", \"NP\"]);\npushButton.AddShortcuts(new List\u003cstring\u003e() {\"RE\", \"NP\"});\n```\n\nThe method design is intended to add only the default shortcut assignment, and does not override the user's settings if they decide to change it.\n\n### ContextMenu Extensions\n\n**ConfigureContextMenu** extension registers an action used to configure a Context menu.\n\n```csharp\napplication.ConfigureContextMenu(menu =\u003e\n{\n    menu.AddMenuItem\u003cCommand\u003e(\"Menu title\");\n    menu.AddMenuItem\u003cCommand\u003e(\"Menu title\")\n        .SetAvailabilityController\u003cController\u003e()\n        .SetToolTip(\"Description\");\n});\n```\n\nYou can also specify your own context menu title. By default, Revit uses the Application name\n\n```csharp\napplication.ConfigureContextMenu(\"Title\", menu =\u003e\n{\n    menu.AddMenuItem\u003cCommand\u003e(\"Menu title\");\n});\n```\n\n**AddMenuItem** extension adds a menu item to the Context Menu.\n\n```csharp\nmenu.AddMenuItem\u003cCommand\u003e(\"Menu title\");\n```\n\n**AddSeparator** extension adds a separator to the Context Menu.\n\n```csharp\nmenu.AddSeparator();\n```\n\n**AddSubMenu** extension adds a sub menu to the Context Menu.\n\n```csharp\nvar subMenu = new ContextMenu();\nsubMenu.AddMenuItem\u003cCommand\u003e(\"Menu title\");\nsubMenu.AddMenuItem\u003cCommand\u003e(\"Menu title\");\n\nmenu.AddSubMenu(\"Sub menu title\", subMenu);\n```\n\n**SetAvailabilityController** extension specifies the class type that decides the availability of menu item.\n\n```csharp\nmenuItem.SetAvailabilityController\u003cController\u003e()\n```\n\n## Document extensions\n\n**GetProfileSymbols** extension gets the profile Family Symbols of the document.\n\n```csharp\nvar symbols = document.GetProfileSymbols(ProfileFamilyUsage.Any, oneCurveLoopOnly: true);\n```\n\n**RelinquishOwnership** extension gets the profile Family Symbols of the document.\n\n```csharp\nvar items = document.RelinquishOwnership(relinquishOptions, transactOptions);\n```\n\n### Document managers extensions\n\n**GetTemporaryGraphicsManager** extension gets a TemporaryGraphicsManager reference of the document.\n\n```csharp\nvar manager = document.GetTemporaryGraphicsManager();\n```\n\n**GetAnalyticalToPhysicalAssociationManager** extension gets a AnalyticalToPhysicalAssociationManager reference of the document.\n\n```csharp\nvar manager = document.GetAnalyticalToPhysicalAssociationManager();\n```\n\n**GetLightGroupManager** extension creates a light group manager object from the given document.\n\n```csharp\nvar manager = document.GetLightGroupManager();\n```\n\n## Geometry extensions\n\n**Distance** extension returns distance between two lines. The lines are considered endless.\n\n```csharp\nvar line1 = Line.CreateBound(new XYZ(0,0,1), new XYZ(1,1,1));\nvar line2 = Line.CreateBound(new XYZ(1,2,2), new XYZ(1,2,2));\nvar distance = line1.Distance(line2);\n```\n\n**Contains** extension determines whether the specified point is contained within this BoundingBox.\n\n```csharp\nvar point = new XYZ(1,1,1);\nvar contains = boundingBox.Contains(point);\n```\n\n**Contains** extension determines whether the specified point is contained within this BoundingBox.\nSet strict mode if the point needs to be fully on the inside of the source. \nA point coinciding with the box border will be considered outside.\n\n```csharp\nvar point = new XYZ(1,1,1);\nvar contains = boundingBox.Contains(point, strict:true);\n```\n\n**Contains** extension determines whether one BoundingBoxXYZ contains another BoundingBoxXYZ.\n\n```csharp\nvar boundingBox2 = new BoundingBoxXYZ();\nvar isContains = boundingBox1.Contains(boundingBox2);\n```\n\n**Contains** extension determines whether one BoundingBoxXYZ contains another BoundingBoxXYZ.\nSet strict mode if the box needs to be fully on the inside of the source.\nCoincident boxes will be considered outside.\n\n```csharp\nvar boundingBox2 = new BoundingBoxXYZ();\nvar isContains = boundingBox1.Contains(boundingBox2, strict:true);\n```\n\n**Overlaps** extension determines whether this BoundingBox overlaps with another BoundingBox.\n\n```csharp\nvar boundingBox2 = new BoundingBoxXYZ();\nvar isContains = boundingBox1.Overlaps(boundingBox2);\n```\n\n**ComputeCentroid** extension computes the geometric center point of the bounding box.\n\n```csharp\nvar center = boundingBox.ComputeCentroid();\n```\n\n**ComputeVertices** extension retrieves the coordinates of the eight vertices that define the bounding box.\n\n```csharp\nvar vertices = boundingBox.ComputeVertices();\n```\n\n**ComputeVolume** extension calculates the volume enclosed by the bounding box.\n\n```csharp\nvar volume = boundingBox.ComputeVolume();\n```\n\n**ComputeSurfaceArea** extension calculates the total surface area of the bounding box.\n\n```csharp\nvar area = boundingBox.ComputeSurfaceArea();\n```\n\n**SetCoordinateX** extension creates an instance of a curve with a new X coordinate.\n\n```csharp\nvar newLine = line.SetCoordinateX(1);\nvar newArc = arc.SetCoordinateX(1);\n```\n\n**SetCoordinateY** extension creates an instance of a curve with a new Y coordinate.\n\n```csharp\nvar newLine = line.SetCoordinateY(1);\nvar newArc = arc.SetCoordinateY(1);\n```\n\n**SetCoordinateZ** extension creates an instance of a curve with a new coordinate.\n\n```csharp\nvar newLine = line.SetCoordinateZ(1);\nvar newArc = arc.SetCoordinateZ(1);\n```\n\n### Element geometry extensions\n\n**JoinGeometry** extension creates clean joins between two elements that share a common face.\n\n```csharp\nelement1.JoinGeometry(element2);\n```\n\n**UnjoinGeometry** extension removes a join between two elements.\n\n```csharp\nelement1.UnjoinGeometry(element2);\n```\n\n**AreElementsJoined** extension determines whether two elements are joined.\n\n```csharp\nvar areJoined = element1.AreElementsJoined(element2);\n```\n\n**GetJoinedElements** extension returns all elements joined to given element.\n\n```csharp\nvar elements = element1.GetJoinedElements();\n```\n\n**SwitchJoinOrder** extension reverses the order in which two elements are joined.\n\n```csharp\nelement1.SwitchJoinOrder();\n```\n\n**IsCuttingElementInJoin** extension determines whether the first of two joined elements is cutting the second element.\n\n```csharp\nvar isCutting = element1.IsCuttingElementInJoin(element2);\n```\n\n## Parameters extensions\n\n**AsBool** extension provides access to the boolean value within the parameter.\n\n```csharp\nbool value = element.FindParameter(\"IsClosed\").AsBool();\n```\n\n**AsColor** extension provides access to the Color within the parameter.\n\n```csharp\nColor value = element.FindParameter(\"Door color\").AsColor();\n```\n\n**AsElement** extension provides access to the Element within the parameter.\n\n```csharp\nElement value = element.FindParameter(\"Door material\").AsElement();\nMaterial value = element.FindParameter(\"Door material\").AsElement\u003cMaterial\u003e();\n```\n\n**Set** extension sets the parameter to a new value.\n\n```csharp\nparameter.Set(true);\nparameter.Set(new Color(66, 69, 96);\n```\n\n**IsBuiltInParameter** extension checks whether a Parameter identifies a built-in parameter.\n\n```csharp\nvar isBuiltIn = parameter.IsBuiltInParameter();\n```\n\n### Document global parameters extensions\n\n**FindGlobalParameter** extension finds whether a global parameter with the given name exists in the input document.\n\n```csharp\nvar parameter = document.FindGlobalParameter(name);\n```\n\n**GetAllGlobalParameters** extension returns all global parameters available in the given document.\n\n```csharp\nvar parameters = document.GetAllGlobalParameters();\n```\n\n**GetGlobalParametersOrdered** extension returns all global parameters in an ordered array.\n\n```csharp\nvar parameters = document.GetGlobalParametersOrdered();\n```\n\n**SortGlobalParameters** extension sorts global parameters in the desired order.\n\n```csharp\ndocument.SortGlobalParameters(ParametersOrder.Ascending);\n```\n\n**MoveGlobalParameterUpOrder** extension moves given global parameter Up in the current order.\n\n```csharp\nvar isMoved = globalParameter.MoveUpOrder();\n```\n\n**MoveGlobalParameterDownOrder** extension moves given global parameter Down in the current order.\n\n```csharp\nvar isMoved = globalParameter.MoveDownOrder();\n```\n\n**IsUniqueGlobalParameterName** extension tests whether a name is unique among existing global parameters of a given document.\n\n```csharp\nvar isUnique = document.IsUniqueGlobalParameterName(name);\n```\n\n**IsValidGlobalParameter** extension tests whether an ElementId is of a global parameter in the given document.\n\n```csharp\nvar isValid = document.IsValidGlobalParameter(parameterId);\n```\n\n**AreGlobalParametersAllowed** extension tests whether global parameters are allowed in the given document.\n\n```csharp\nvar isAllowed = document.AreGlobalParametersAllowed();\n```\n\n\n## FilteredElementCollector extensions\n\nThis set of extensions encapsulates all the work of searching for elements in the Revit database.\n\n**GetElements** a generic method which constructs a new FilteredElementCollector that will search and filter the set of elements in a document.\nFilter criteria are not applied to the method.\n\n```csharp\nvar elements = document.GetElements().WhereElementIsViewIndependent().ToElements();\nvar elements = document.GetElements(elementIds).WhereElementIsViewIndependent().ToElements();\nvar elements = document.GetElements(viewId).ToElements();\n```\n\nThe remaining methods contain a ready implementation of the collector, with filters applied:\n\n```csharp\nvar elements = document.GetInstances();\nvar elements = document.GetInstances(new ElementParameterFilter());\nvar elements = document.GetInstances([elementParameterFilter, logicalFilter]);\n\nvar elements = document.GetInstances(BuiltInCategory.OST_Walls);\nvar elements = document.GetInstances(BuiltInCategory.OST_Walls, new ElementParameterFilter());\nvar elements = document.GetInstances(BuiltInCategory.OST_Walls, [elementParameterFilter, logicalFilter]);    \n\nvar elements = document.EnumerateInstances();\nvar elements = document.EnumerateInstances(new ElementParameterFilter());\nvar elements = document.EnumerateInstances([elementParameterFilter, logicalFilter]);\n\nvar elements = document.EnumerateInstances(BuiltInCategory.OST_Walls);\nvar elements = document.EnumerateInstances(BuiltInCategory.OST_Walls, new ElementParameterFilter());\nvar elements = document.EnumerateInstances(BuiltInCategory.OST_Walls, [elementParameterFilter, logicalFilter]);   \n\nvar elements = document.EnumerateInstances\u003cWall\u003e();\nvar elements = document.EnumerateInstances\u003cWall\u003e(new ElementParameterFilter());\nvar elements = document.EnumerateInstances\u003cWall\u003e(new [elementParameterFilter, logicalFilter]);\n\nvar elements = document.EnumerateInstances\u003cWall\u003e(BuiltInCategory.OST_Walls);\nvar elements = document.EnumerateInstances\u003cWall\u003e(BuiltInCategory.OST_Walls, new ElementParameterFilter());\nvar elements = document.EnumerateInstances\u003cWall\u003e(BuiltInCategory.OST_Walls, [elementParameterFilter, logicalFilter]);   \n```\n\nThe same overloads exist for InstanceIds, Type, TypeIds:\n\n```csharp\nvar types = document.GetTypes();\nvar types = document.GetTypeIds();\nvar types = document.GetInstanceIds();\nvar types = document.EnumerateTypes();\nvar types = document.EnumerateTypeIds();\nvar types = document.EnumerateInstanceIds();\n```\n\n**Remarks**: `Get` methods are faster than `Enumerate` due to RevitApi internal optimizations.\nHowever, enumeration allows for more flexibility in finding elements.\n\nDon't try to call `GetInstances().Select().Tolist()` instead of `EnumerateInstances().Select().Tolist()`, you will degrade performance.\n\n## ForgeTypeId extensions\n\n**IsSpec** extension Checks whether a ForgeTypeId identifies a spec.\n\n```csharp\nvar isSpec = forgeId.IsSpec();\n```\n\n**IsBuiltInGroup** extension checks whether a ForgeTypeId identifies a built-in parameter group.\n\n```csharp\nvar isGroup = forgeId.IsBuiltInGroup();\n```\n\n**IsBuiltInParameter** extension checks whether a ForgeTypeId identifies a built-in parameter.\n\n```csharp\nvar isBuiltInParameter = forgeId.IsBuiltInParameter();\n```\n\n**IsSymbol** extension checks whether a ForgeTypeId identifies a symbol.\n\n```csharp\nvar isSymbol = symbolTypeId.IsSymbol();\n```\n\n**IsUnit** extension checks whether a ForgeTypeId identifies a unit.\n\n```csharp\nvar isUnit = unitTypeId.IsUnit();\n```\n\n**IsValidDataType** extension returns true if the given ForgeTypeId identifies a valid parameter data type.\n\n```csharp\nvar isValid = forgeId.IsValidDataType();\n```\n\n**IsValidUnit** extension checks whether a unit is valid for a given measurable spec.\n\n```csharp\nvar isValid = specTypeId.IsValidUnit(unitTypeId);\n```\n\n**IsMeasurableSpec** extension checks whether a ForgeTypeId identifies a spec associated with units of measurement.\n\n```csharp\nvar isMeasurable = specTypeId.IsMeasurableSpec(unitTypeId);\n```\n\n**GetBuiltInParameter** extension gets the BuiltInParameter value corresponding to built-in parameter identified by the given ForgeTypeId.\n\n```csharp\nvar builtInParameter = forgeId.GetBuiltInParameter();\n```\n\n**GetParameterTypeId** extension gets the ForgeTypeId identifying the built-in parameter corresponding to the given BuiltInParameter value.\n\n```csharp\nvar forgeId = builtInParameter.GetParameterTypeId();\n```\n\n**GetDiscipline** extension gets the discipline for a given measurable spec.\n\n```csharp\nvar disciplineId = specTypeId.GetDiscipline();\n```\n\n**GetValidUnits** extension gets the identifiers of all valid units for a given measurable spec.\n\n```csharp\nvar unitIds = specTypeId.GetValidUnits();\n```\n\n**GetTypeCatalogStringForSpec** extension gets the string used in type catalogs to identify a given measurable spec.\n\n```csharp\nvar catalog = specTypeId.GetTypeCatalogStringForSpec();\n```\n\n**GetTypeCatalogStringForUnit** extension gets the string used in type catalogs to identify a given unit.\n\n```csharp\nvar catalog = unitTypeId.GetTypeCatalogStringForUnit();\n```\n\n**DownloadCompanyName** extension downloads the name of the given parameter's owning account and records it in the given document.\nIf the owning account's name is already recorded in the given document, this method returns the name without downloading it again.\n\n```csharp\nvar name = forgeId.DownloadCompanyName(document);\n```\n\n**DownloadParameterOptions** extension retrieves settings associated with the given parameter from the Parameters Service.\n\n```csharp\nvar options = forgeId.DownloadParameterOptions(document);\n```\n\n**DownloadParameter** extension creates a shared parameter element in the given document according to a parameter definition downloaded from the Parameters Service.\n\n```csharp\nvar sharedParameter = forgeId.DownloadParameter(document, options);\n```\n\n## Unit Extensions\n\n**FromMillimeters** extension converts millimeters to internal Revit number format (feet).\n\n```csharp\nvar value = 69d.FromMillimeters(); // 0.226\n```\n\n**ToMillimeters** extension converts a Revit internal format value (feet) to millimeters.\n\n```csharp\nvar value = 69d.ToMillimeters(); // 21031\n```\n\n**FromMeters** extension converts meters to internal Revit number format (feet).\n\n```csharp\nvar value = 69d.FromMeters(); // 226.377\n```\n\n**ToMeters** extension converts a Revit internal format value (feet) to meters.\n\n```csharp\nvar value = 69d.ToMeters(); // 21.031\n```\n\n**FromInches** extension converts inches to internal Revit number format (feet).\n\n```csharp\nvar value = 69d.FromInches(); // 5.750\n```\n\n**ToInches** extension converts a Revit internal format value (feet) to inches.\n\n```csharp\nvar value = 69d.ToInches(); // 827.999\n```\n\n**FromDegrees** extension converts degrees to internal Revit number format (radians).\n\n```csharp\nvar value = 69d.FromDegrees(); // 1.204\n```\n\n**ToDegrees** extension converts a Revit internal format value (radians) to degrees.\n\n```csharp\nvar value = 69d.ToDegrees(); // 3953\n```\n\n**FromUnit(UnitTypeId)** extension converts the specified unit type to internal Revit number format.\n\n```csharp\nvar value = 69d.FromUnit(UnitTypeId.Celsius); // 342.15\n```\n\n**ToUnit(UnitTypeId)** extension converts a Revit internal format value to the specified unit type.\n\n```csharp\nvar value = 69d.ToUnit(UnitTypeId.Celsius); // -204.15\n```\n\n**FormatUnit** extension formats a number with units into a string.\n\n```csharp\nvar value = document.GetUnits().FormatUnit(SpecTypeId.Length, 69, false); // 21031\nvar value = document.GetUnits().FormatUnit(SpecTypeId.Length, 69, false, new FormatValueOptions {AppendUnitSymbol = true}); // 21031 mm\n```\n\n**TryParse** extension parses a formatted string into a number with units if possible.\n\n```csharp\nvar isParsec = document.GetUnits().TryParse(SpecTypeId.Length, \"21031 mm\", out var value); // 69\n```\n\n## Label Extensions\n\n**ToLabel** extension convert Enum to user-visible name.\n\n```csharp\nvar label = BuiltInCategory.OST_Walls.ToLabel(); // \"Walls\"\nvar label = BuiltInParameter.WALL_TOP_OFFSET.ToLabel(); // \"Top Offset\"\nvar label = BuiltInParameter.WALL_TOP_OFFSET.ToLabel(LanguageType.Russian); // \"Смещение сверху\"\nvar label = BuiltInParameterGroup.PG_LENGTH.ToLabel(); // \"Length\"\nvar label = DisplayUnitType.DUT_KILOWATTS.ToLabel(); // \"Kilowatts\"\n```\n\n**ToLabel** extension convert ForgeTypeId to user-visible name.\n\n```csharp\nvar label = ParameterType.Length.ToLabel(); // \"Length\"\nvar label = DisciplineTypeId.Hvac.ToLabel(); // \"HVAC\"\nvar label = GroupTypeId.Geometry.ToLabel(); // \"Dimensions\"\nvar label = ParameterTypeId.DoorCost.ToLabel(); // \"Cost\"\nvar label = SpecTypeId.SheetLength.ToLabel(); // \"Sheet Length\"\nvar label = SymbolTypeId.Hour.ToLabel(); // \"h\"\nvar label = UnitTypeId.Hertz.ToLabel(); // \"Hertz\"\n```\n\n**ToDisciplineLabel** extension convert ForgeTypeId to user-visible name a discipline.\n\n```csharp\nvar label = DisciplineTypeId.Hvac.ToDisciplineLabel(); // \"HVAC\"\n```\n\n**ToGroupLabel** extension converts ForgeTypeId to user-visible name for a built-in parameter group.\n\n```csharp\nvar label = GroupTypeId.Geometry.ToGroupLabel(); // \"Dimensions\"\n```\n\n**ToParameterLabel** extension converts ForgeTypeId to user-visible name for a built-in parameter.\n\n```csharp\nvar label = ParameterTypeId.DoorCost.ToParameterLabel(); // \"Cost\"\n```\n\n**ToSpecLabel** extension converts ForgeTypeId to user-visible name for a spec.\n\n```csharp\nvar label = SpecTypeId.SheetLength.ToSpecLabel(); // \"Sheet Length\"\n```\n\n**ToSymbolLabel** extension convert ForgeTypeId to user-visible name for a symbol.\n\n```csharp\nvar label = SymbolTypeId.Hour.ToSymbolLabel(); // \"h\"\n```\n\n**ToUnitLabel** extension converts ForgeTypeId to user-visible name for a unit.\n\n```csharp\nvar label = UnitTypeId.Hertz.ToUnitLabel(); // \"Hertz\"\n```\n\n## Color extensions\n\n**ToHex** extension returns a hexadecimal representation of a color.\n\n```csharp\nvar hex = color.ToHex();\n```\n\n**ToHexInteger** extension returns a hexadecimal integer representation of a color.\n\n```csharp\nvar hexInteger = color.ToHexInteger();\n```\n\n**ToRgb** extension returns an RGB representation of a color.\n\n```csharp\nvar rgb = color.ToRgb();\n```\n\n**ToHsl** extension returns a HSL representation of a color.\n\n```csharp\nvar hsl = color.ToHsl();\n```\n\n**ToHsv** extension returns a HSV representation of a color.\n\n```csharp\nvar hsv = color.ToHsv();\n```\n\n**ToCmyk** extension returns a CMYK representation of a color.\n\n```csharp\nvar cmyk = color.ToCmyk();\n```\n\n**ToHsb** extension returns a HSB representation of a color.\n\n```csharp\nvar hsb = color.ToHsb();\n```\n\n**ToHsi** extension returns a HSI representation of a color.\n\n```csharp\nvar hsi = color.ToHsi();\n```\n\n**ToHwb** extension returns a HWB representation of a color.\n\n```csharp\nvar hwb = color.ToHwb();\n```\n\n**ToNCol** extension returns a NCol representation of a color.\n\n```csharp\nvar ncol = color.ToNCol();\n```\n\n**ToCielab** extension returns a Cielab representation of a color.\n\n```csharp\nvar cielab = color.ToCielab();\n```\n\n**ToCieXyz** extension returns a CieXyz representation of a color.\n\n```csharp\nvar xyz = color.ToCieXyz();\n```\n\n**ToFloat** extension returns a Float representation of a color.\n\n```csharp\nvar float = color.ToFloat();\n```\n\n**ToDecimal** extension returns a Decimal representation of a color.\n\n```csharp\nvar decimal = color.ToDecimal();\n```\n\n## Family extensions\n\n**CanConvertToFaceHostBased** extension indicates whether the family can be converted to face host based.\n\n```csharp\nvar canConvert = family.CanConvertToFaceHostBased();\n```\n\n**ConvertToFaceHostBased** extension converts a family to be face host based.\n\n```csharp\nfamily.ConvertToFaceHostBased();\n```\n\n## HostObject extensions\n\n**GetBottomFaces** extension returns the bottom faces for the host object.\n\n```csharp\nfloor.GetBottomFaces();\n```\n\n**GetTopFaces** extension returns the top faces for the host object.\n\n```csharp\nfloor.GetTopFaces();\n```\n\n**GetSideFaces** extension returns the major side faces for the host object.\n\n```csharp\nwall.GetSideFaces(ShellLayerType.Interior);\n```\n\n## Plumbing extensions\n\n**ConnectPipePlaceholdersAtElbow** extension connects placeholders that look like an elbow connection.\n\n```csharp\nvar isConnected = connector1.ConnectPipePlaceholdersAtElbow(connector2);\n```\n\n**ConnectPipePlaceholdersAtTee** extension connects three placeholders that look like a Tee connection.\n\n```csharp\nvar isConnected = connector1.ConnectPipePlaceholdersAtTee(connector2, connector3);\n```\n\n**ConnectPipePlaceholdersAtCross** extension connects placeholders that look like a Cross connection.\n\n```csharp\nvar isConnected = connector1.ConnectPipePlaceholdersAtCross(connector2, connector3, connector4);\n```\n\n**PlaceCapOnOpenEnds** extension places caps on the open connectors of the pipe curve.\n\n```csharp\npipe.PlaceCapOnOpenEnds();\npipe.PlaceCapOnOpenEnds(typeId);\n```\n\n**HasOpenConnector** extension checks if there is open piping connector for the given pipe curve.\n\n```csharp\nvar hasOpenConnector = pipe.HasOpenConnector();\n```\n\n**BreakCurve** extension breaks the pipe curve into two parts at the given position.\n\n```csharp\nvar pipeCurve = pipe.BreakCurve(new XYZ(1, 1, 1));\n```\n\n## Solid extensions\n\n**Clone** extension creates a new Solid, which is a copy of the input Solid.\n\n```csharp\nvar clone = solid.Clone();\n```\n\n**CreateTransformed** extension creates a new Solid which is the transformation of the input Solid.\n\n```csharp\nvar transformed = solid.CreateTransformed(Transform.CreateRotationAtPoint());\nvar transformed = solid.CreateTransformed(Transform.CreateReflection());\n```\n\n**SplitVolumes** extension splits a solid geometry into several solids.\n\n```csharp\nvar solids = solid.SplitVolumes();\n```\n\n**IsValidForTessellation** extension tests if the input solid or shell is valid for tessellation.\n\n```csharp\nvar isValid = solid.IsValidForTessellation();\n```\n\n**TessellateSolidOrShell** extension facets (i.e., triangulates) a solid or an open shell.\n\n```csharp\nvar tesselation = solid.TessellateSolidOrShell();\n```\n\n**FindAllEdgeEndPointsAtVertex** extension finds all EdgeEndPoints at a vertex identified by the input EdgeEndPoint.\n\n```csharp\nvar point = edgeEndPoint.FindAllEdgeEndPointsAtVertex();\n```\n\n### Element solid cut extensions\n\n**GetCuttingSolids** extension gets all the solids which cut the input element.\n\n```csharp\nvar solids = element.GetCuttingSolids();\n```\n\n**GetSolidsBeingCut** extension gets all the solids which are cut by the input element.\n\n```csharp\nvar solids = element.GetSolidsBeingCut();\n```\n\n**IsAllowedForSolidCut** extension validates that the element is eligible for a solid-solid cut.\n\n```csharp\nvar isAllowed = element.IsAllowedForSolidCut();\n```\n\n**IsElementFromAppropriateContext** extension validates that the element is from an appropriate document.\n\n```csharp\nvar fromContext = element.IsElementFromAppropriateContext();\n```\n\n**CanElementCutElement** extension verifies if the cutting element can add a solid cut to the target element.\n\n```csharp\nvar canCut = element1.CanElementCutElement(element2, out var reason);\n```\n\n**CutExistsBetweenElements** extension checks that if there is a solid-solid cut between two elements.\n\n```csharp\nvar isCutExists = element1.CutExistsBetweenElements(element2, out var isFirstCuts);\n```\n\n**AddCutBetweenSolids** extension adds a solid-solid cut for the two elements.\n\n```csharp\nelement1.AddCutBetweenSolids(element2);\n```\n\n**RemoveCutBetweenSolids** extension removes the solid-solid cut between the two elements if it exists.\n\n```csharp\nelement1.RemoveCutBetweenSolids(element2);\n```\n\n**SplitFacesOfCuttingSolid** extension removes the solid-solid cut between the two elements if it exists.\n\n```csharp\nelement1.SplitFacesOfCuttingSolid(element2);\n```\n\n## View extensions\n\n**GetTransformFromViewToView** extension returns a transformation that is applied to elements when copying from one view to another view.\n\n```csharp\nvar transform = view1.GetTransformFromViewToView(view2);\n```\n\n### View managers extensions\n\n**CreateSpatialFieldManager** extension creates SpatialField for the given view.\n\n```csharp\nvar manager = view.CreateSpatialFieldManager(numberOfMeasurements: 69);\n```\n\n**GetSpatialFieldManager** extension retrieves SpatialField manager for the given view.\n\n```csharp\nvar manager = view.GetSpatialFieldManager();\n```\n\n## Imperial Extensions\n\n**ToFraction** extension converts a double value representing a measurement in feet to its string representation in the Imperial system, expressed as feet, inches, and fractional inches.\n\n```csharp\nvar imperial = 0.0123.ToFraction(); // 1/8\"\nvar imperial = 12.011.ToFraction(); // 12'-1/8\"\nvar imperial = 25.222.ToFraction(); // 25'-2 1/8\"\nvar imperial = 0.0123.ToFraction(8); // 1/8\"\nvar imperial = 12.006.ToFraction(16); // 12'-1/16\"\nvar imperial = 25.222.ToFraction(32); // 25'-2 21/32\"\n```\n\n**FromFraction** extension converts a string representation of a measurement in the Imperial system (feet and inches) to a double value.\n\n```csharp\nvar value = \"17/64\\\"\".FromFraction(); // 0.092\nvar value = \"1'1.75\".FromFraction(); // 1.145\nvar value = \"-69'-69\\\"\".FromFraction(); // -74.75\nvar value = \"2'-1 15/64\\\"\".FromFraction(); // 2.102\n```\n\n**TryFromFraction** extension converts the textual representation of the Imperial system number to number.\n\n```csharp\nvar converted = \"1'\".TryFromFraction(out var value); // true\nvar converted = \"69\\\"\".TryFromFraction(out var value); // true\nvar converted = \"-2'-1 15/64\\\"\".TryFromFraction(out var value); // true\nvar converted = \"value\".TryFromFraction(out var value); // false\n```\n\n## System Extensions\n\n**Cast\u003cT\u003e** extension casts an object to the specified type.\n\n```csharp\nvar width = element.Cast\u003cWall\u003e().Width;\nvar location = element.Location.Cast\u003cLocationCurve\u003e().Curve;\nvar faces = element.Cast\u003cHostObject\u003e().GetSideFaces();\n```\n\n**Round** extension rounds the value to the specified precision or 1e-9 precision specified in Revit Api.\n\n```csharp\nvar rounded = 6.56170000000000000000000001.Round(); // 6.5617\nvar rounded = 6.56170000000000000000000001.Round(0); // 7\n```\n\n**IsAlmostEqual** extension compares two numbers within specified precision or 1e-9 precision specified in Revit Api.\n\n```csharp\nvar isRqual = 6.56170000000000000000000001.IsAlmostEqual(6.5617); // true\nvar isEqual = 6.56170000000000000000000001.IsAlmostEqual(6.6, 1e-1); // true\n```\n\n**IsNullOrEmpty** extension indicates whether the specified string is null or an empty string.\n\n```csharp\nvar isEmpty = \"\".IsNullOrEmpty(); // true\nvar isEmpty = null.IsNullOrEmpty(); // true\n```\n\n**IsNullOrWhiteSpace** extension indicates whether a specified string is null, empty, or consists only of white-space characters.\n\n```csharp\nvar isEmpty = \" \".IsNullOrWhiteSpace(); // true\nvar isEmpty = null.IsNullOrWhiteSpace(); // true\n```\n\n**AppendPath** extension combines paths.\n\n```csharp\nvar path = \"C:/Folder\".AppendPath(\"AddIn\"); // C:/Folder/AddIn\nvar path = \"C:/Folder\".AppendPath(\"AddIn\", \"file.txt\"); // C:/Folder/AddIn/file.txt\n```\n\n**Contains** indicating whether a specified substring occurs within this string with `StringComparison` support.\n\nAvailable only for .NET Framework builds. .NET Core has a built-in support for this method.\n\n```csharp\nvar isContains = \"Revit extensions\".Contains(\"Revit\", StringComparison.OrdinalIgnoreCase); // true\nvar isContains = \"Revit extensions\".Contains(\"revit\", StringComparison.OrdinalIgnoreCase); // true\nvar isContains = \"Revit extensions\".Contains(\"REVIT\", StringComparison.OrdinalIgnoreCase); // true\nvar isContains = \"Revit extensions\".Contains(\"invalid\", StringComparison.OrdinalIgnoreCase); // false\n```\n\n**Show** extension opens a window and returns without waiting for the newly opened window to close.\nSets the owner of a child window. Applicable for modeless windows to be attached to Revit.\n\n```csharp\nnew RevitAddinView.Show(uiApplication.MainWindowHandle)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnice3point%2Frevitextensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnice3point%2Frevitextensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnice3point%2Frevitextensions/lists"}