Revit API Developer's Guide MD 변환본 추가 (368 페이지)
Revit 2026 공식 Developer's Guide HTML → MD 변환. Output/revit-api-guide/에 8개 카테고리 폴더로 정리. CLAUDE.md에 참조 규칙 추가, .gitignore에 .scratch/ 제외. 소스: help.autodesk.com/view/RVT/2026/ENU (CC BY-NC-SA 3.0) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Collections and Iterators
|
||||
|
||||
# Collections and Iterators
|
||||
|
||||
In the Revit Platform API, Collections and Iterators are generic and type safe.
|
||||
|
||||
All collections implement the IEnumerable interface and all relevant iterators implement the IEnumerator interface. As a result, all methods and properties are implemented in the Revit Platform API and can play a role in the relevant collections.
|
||||
|
||||
Implementing all of the collections is similar. The following example uses ModelCurveArray to demonstrate how to use the main collection properties:
|
||||
|
||||
**Code Region 9-2: Using collections**
|
||||
---
|
||||
|
||||
|
||||
public void UsingCollections(Document document)
|
||||
{
|
||||
UIDocument uidoc = new UIDocument(document);
|
||||
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
|
||||
|
||||
// Store the ModelLine references
|
||||
ModelCurveArray lineArray = new ModelCurveArray();
|
||||
|
||||
// … Store operation
|
||||
Autodesk.Revit.DB.ElementId id = new Autodesk.Revit.DB.ElementId((long)131943); //assume 131943 is a model line element id
|
||||
lineArray.Append(document.GetElement(id) as ModelLine);
|
||||
|
||||
// use Size property of Array
|
||||
TaskDialog.Show("Revit","Before Insert: " + lineArray.Size + " in lineArray.");
|
||||
|
||||
// use IsEmpty property of Array
|
||||
if (!lineArray.IsEmpty)
|
||||
{
|
||||
// use Item(int) property of Array
|
||||
ModelCurve modelCurve = lineArray.get_Item(0) as ModelCurve;
|
||||
|
||||
// erase the specific element from the set of elements
|
||||
selectedIds.Remove(modelCurve.Id);
|
||||
|
||||
// create a new model line and insert to array of model line
|
||||
SketchPlane sketchPlane = modelCurve.SketchPlane;
|
||||
|
||||
XYZ startPoint = new XYZ(0, 0, 0); // the start point of the line
|
||||
XYZ endPoint = new XYZ(10, 10, 0); // the end point of the line
|
||||
// create geometry line
|
||||
Line geometryLine = Line.CreateBound(startPoint, endPoint);
|
||||
|
||||
// create the ModelLine
|
||||
ModelLine line = document.Create.NewModelCurve(geometryLine, sketchPlane) as ModelLine;
|
||||
|
||||
lineArray.Insert(line, lineArray.Size - 1);
|
||||
}
|
||||
|
||||
TaskDialog.Show("Revit","After Insert: " + lineArray.Size + " in lineArray.");
|
||||
|
||||
// use the Clear() method to remove all elements in lineArray
|
||||
lineArray.Clear();
|
||||
|
||||
TaskDialog.Show("Revit","After Clear: " + lineArray.Size + " in lineArray.");
|
||||
}
|
||||
|
||||
**Parent page:** [Collections](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Collections_html.html)
|
||||
@@ -0,0 +1,35 @@
|
||||
# Interface
|
||||
|
||||
# Interface
|
||||
|
||||
The following sections discuss interface-related collection types.
|
||||
|
||||
### IEnumerable
|
||||
|
||||
The IEnumerable interface is in the System.Collections namespace. It exposes the enumerator, which supports a simple iteration over a non-generic collection. The GetEnumerator() method gets an enumerator that implements this interface. The returned [IEnumerator](http://msdn2.microsoft.com/en-us/library/system.collections.ienumerator.aspx) object is iterated throughout the collection. The GetEnumerator() method is used implicitly by foreach loops in C#.
|
||||
|
||||
### IEnumerator
|
||||
|
||||
The IEnumerator interface is in the System.Collections namespace. It supports a simple iteration over a non-generic collection. IEnumerator is the base interface for all non-generic enumerators. The foreach statement in C# hides the enumerator's complexity.
|
||||
|
||||
Note: Using foreach is recommended instead of directly manipulating the enumerator.
|
||||
|
||||
Enumerators are used to read the collection data, but they cannot be used to modify the underlying collection. Use IEnumerator as follows:
|
||||
|
||||
* Initially, the enumerator is positioned in front of the first element in the collection. However, it is a good idea to always call Reset() when you first obtain the enumerator.
|
||||
* The Reset() method moves the enumerator back to the original position. At this position, calling the Current property throws an exception.
|
||||
* Call the MoveNext() method to advance the enumerator to the collection's first element before reading the current iterator value.
|
||||
* The Current property returns the same object until either the MoveNext() method or Reset() method is called. The MoveNext() method sets the current iterator to the next element.
|
||||
* If MoveNext passes the end of the collection, the enumerator is positioned after the last element in the collection and MoveNext returns false.
|
||||
* When the enumerator is in this position, subsequent calls to the MoveNext also return false.
|
||||
* If the last call to the MoveNext returns false, calling the Current property throws an exception.
|
||||
* To set the current iterator to the first element in the collection again, call the Reset() method followed by MoveNext().
|
||||
* An enumerator remains valid as long as the collection remains unchanged.
|
||||
* If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is invalidated and the next call to the MoveNext() or the Reset() method throws an InvalidOperationException.
|
||||
* If the collection is modified between the MoveNext and the current iterator, the Current property returns to the specified element, even if the enumerator is already invalidated.
|
||||
|
||||
|
||||
|
||||
Note: All calls to the Reset() method must result in the same state for the enumerator. The preferred implementation is to move the enumerator to the collection beginning, before the first element. This invalidates the enumerator if the collection is modified after the enumerator was created, which is consistent with the MoveNext() and the Current properties.
|
||||
|
||||
**Parent page:** [Collections](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Collections_html.html)
|
||||
@@ -0,0 +1,16 @@
|
||||
# Collections
|
||||
|
||||
# Collections
|
||||
|
||||
Most Revit Platform API properties and methods use .NET Framework collection classes when providing access to a group of related items.
|
||||
|
||||
The IEnumerable and IEnumerator interfaces implemented in Revit collection types are defined in the System.Collection namespace.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Interface](Collections/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Collections_Interface_html.html)
|
||||
* [Collections and Iterators](Collections/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Collections_Collections_and_Iterators_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,22 @@
|
||||
# Aligning Elements
|
||||
|
||||
# Aligning Elements
|
||||
|
||||
The ItemFactoryBase.NewAlignment() method can create a new locked alignment between two references. These two references must be one of the following combinations:
|
||||
|
||||
* 2 planar faces
|
||||
* 2 lines
|
||||
* line and point
|
||||
* line and reference plane
|
||||
* 2 arcs
|
||||
* 2 cylindrical faces
|
||||
|
||||
|
||||
|
||||
These references must be already geometrically aligned as this function will not force them to become aligned. If the alignment can be created a new Dimension object is returned representing the locked alignment. Otherwise an exception will be thrown.
|
||||
|
||||
The NewAlignment() method also requires a view which will determine the orientation of the alignment.
|
||||
|
||||
See the CreateTruss example in the FamilyCreation folder included with the SDK Samples. It has several examples of the use of NewAlignment(), such as locking the bottom chord of a new truss to a bottom reference plane.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,29 @@
|
||||
# Copying Elements
|
||||
|
||||
# Copying Elements
|
||||
|
||||
The ElementTransformUtils class provides several static methods to copy one or more elements from one place to another, either within the same document or view, or to a different document or view.
|
||||
|
||||
**Table: Copy Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`CopyElement( Document, ElementId, XYZ)` | Copies an element and places the copy at a location indicated by a given transformation..
|
||||
`CopyElements(Document, ICollection<ElementId>, XYZ)` | Copies a set of elements and places the copies at a location indicated by a given translation.
|
||||
`CopyElements(Document, ICollection<ElementId>, Document, Transform, CopyPasteOptions)` | Copies a set of elements from source document to destination document.
|
||||
`CopyElements(View, ICollection<ElementId>, View, Transform, CopyPasteOptions)` | Copies a set of elements from source view to destination view.
|
||||
|
||||
All of the methods return a collection of ElementIds of the newly created elements, including CopyElement(). The collection includes any elements created due to dependencies.
|
||||
|
||||
The method for copying from one document to another can be used for copying non-view specific elements only. Copies are placed at their respective original location or locations specified by the optional transformation.
|
||||
|
||||
View-specific elements should be copied using the method that copies from one view to another. That method can be used for both view-specific and model elements however, drafting views cannot be used as a destination for model elements. The pasted elements are repositioned to ensure proper placement in the destination view. For example, the elevation is changed when copying from one level to another. An additional transformation within the destination view can be performed by providing the optional Transform argument. This additional transformation must be within the plane of the destination view.
|
||||
|
||||
When copying from one view to another, both the source and destination views must be 2D graphics views capable of drawing details and view-specific elements, such as floor and ceiling plans, elevations, sections, or drafting views. The ElementTransformUtils.GetTransformFromViewToView() method will return the transformation that is applied to elements when copying from a source view to a destination view.
|
||||
|
||||
When copying between views or between documents, an optional CopyPasteOptions parameter may be set to override default copy/paste settings. By default, in the event of duplicate type names during a paste operation, Revit displays a modal dialog with options to either copy types with unique names only, or to cancel the operation. CopyPasteOptions can be used to specify a custom handler, using the IDuplicateTypeNamesHandler interface, to handle duplicate type names.
|
||||
|
||||
See the Duplicate Views sample in the Revit SDK for a detailed example of copying between documents and between views.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,40 @@
|
||||
# Creating Arrays of Elements
|
||||
|
||||
# Creating Arrays of Elements
|
||||
|
||||
The Revit Platform API provides two classes, LinearArray and RadialArray to array one or more elements in the project. These classes provide static methods to create a linear or radial array of one or more selected components. Linear arrays represent an array created along a line from one point, while radial arrays represent an array created along an arc.
|
||||
|
||||
As an example of using an array, you can select a door and windows located in the same wall and then create multiple instances of the door, wall, and window configuration.
|
||||
|
||||
Both LinearArray and RadialArray also provide methods to array one or several elements without being grouped and associated. Although similar to the Create() methods for arraying elements, each resulting element is independent of the others, and can be manipulated without affecting the other elements. See the tables below for more information on the methods available to create linear or radial arrays.
|
||||
|
||||
**Table 22: LinearArray Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`Create(Document, View, ElementId, int, XYZ, ArrayAnchorMember)` | Array one element in the project by a specified number.
|
||||
`Create(Document, View, ICollection<ElementId>, int, XYZ, ArrayAnchorMember)` | Array a set of elements in the project by a specified number.
|
||||
`ArrayElementWithoutAssociation(Document, View, ElementId, int, XYZ, ArrayAnchorMember)` | Array one element in the project by a specified number. The resulting elements are not associated with a linear array.
|
||||
`ArrayElementsWithoutAssociation(Document, View, ICollection<ElementId>, int, XYZ, ArrayAnchorMember)` | Array a set of elements in the project by a specified number. The resulting elements are not associated with a linear array.
|
||||
|
||||
**Table 23: RadialArray Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`Create(Document, View, ElementId, int, Line, double, ArrayAnchorMember)` | Array one element in the project based on an input rotation axis.
|
||||
`ArrayElementWithoutAssociation(Document, View, ElementId, int, Line, double, ArrayAnchorMember)` | Array one element in the project based on an input rotation axis.. The resulting elements are not associated with a linear array.
|
||||
`ArrayElementsWithoutAssociation(Document, View, ICollection<ElementId>, int, Line, double, ArrayAnchorMember)` | Array a set of elements in the project based on an input rotation axis.. The resulting elements are not associated with a linear array.
|
||||
|
||||
The methods for arraying elements are useful if you need to create several instances of a component and manipulate them simultaneously. Every instance in an array can be a member of a group.
|
||||
|
||||
Note: When using the methods for arraying elements, the following rules apply:
|
||||
|
||||
* When performing Linear and Radial Array operations, elements dependent on the arrayed elements are also arrayed.
|
||||
* Some elements cannot be arrayed because they cannot be grouped. See the Revit User's Guide for more information about restrictions on groups and arrays.
|
||||
* Arrays are not supported by most annotation symbols.
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,65 @@
|
||||
# Deleting Elements
|
||||
|
||||
# Deleting Elements
|
||||
|
||||
The Revit Platform API provides Delete() methods to delete one or more elements in the project.
|
||||
|
||||
**Table 23: Delete Members**
|
||||
|
||||
**Member** | **Description**
|
||||
---|---
|
||||
Delete(ElementId) | Delete an element from the project using the element ID
|
||||
Delete([ICollection](http://msdn2.microsoft.com/en-us/library/92t2ye13)) | Delete several elements from the project by their IDs.
|
||||
The first method deletes a single element based on its Id, as shown in the example below. **Code Region: Deleting an element based on ElementId**
|
||||
---
|
||||
|
||||
|
||||
private void DeleteElement(Autodesk.Revit.DB.Document document, Element element)
|
||||
{
|
||||
// Delete an element via its id
|
||||
Autodesk.Revit.DB.ElementId elementId = element.Id;
|
||||
ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = document.Delete(elementId);
|
||||
|
||||
if (0 == deletedIdSet.Count)
|
||||
{
|
||||
throw new Exception("Deleting the selected element in Revit failed.");
|
||||
}
|
||||
|
||||
String prompt = "The selected element has been removed and ";
|
||||
prompt += deletedIdSet.Count - 1;
|
||||
prompt += " more dependent elements have also been removed.";
|
||||
|
||||
// Give the user some information
|
||||
TaskDialog.Show("Revit", prompt);
|
||||
}
|
||||
|
||||
Note: When an element is deleted, any child elements associated with that element are also deleted, as indicated in the sample above.
|
||||
|
||||
The API also provides a way to delete several elements.
|
||||
|
||||
**Code Region: Deleting multiple elements based on Id**
|
||||
---
|
||||
|
||||
|
||||
public void DeleteSelected(Document document)
|
||||
{
|
||||
// Delete all the selected elements via the set of elements
|
||||
UIDocument uidoc = new UIDocument(document);
|
||||
ICollection<ElementId> elements = uidoc.Selection.GetElementIds();
|
||||
ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = document.Delete(elements);
|
||||
|
||||
if (0 == deletedIdSet.Count)
|
||||
{
|
||||
throw new Exception("Deleting the selected elements in Revit failed.");
|
||||
}
|
||||
|
||||
TaskDialog.Show("Revit","The selected element has been removed.");
|
||||
}
|
||||
|
||||
Note: After you delete the elements, any references to the deleted elements become invalid and throw an exception if they are accessed.
|
||||
|
||||
## Element Dependencies
|
||||
|
||||
Element.GetDependentElements() returns a list of ids of elements which are "children" of this element; that is, those elements which will be deleted along with this element. The method optionally takes an ElementFilter which can be used to reduce the output list to the collection of elements matching specific criteria.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,91 @@
|
||||
# Grouping Elements
|
||||
|
||||
# Grouping Elements
|
||||
|
||||
The Revit API uses the Creation.Document.NewGroup() method to select an element or multiple elements or groups and then combine them. With each instance of a group that you place, there is associatively among them. For example, you create a group with a bed, walls, and window and then place multiple instances of the group in your project. If you modify a wall in one group, it changes for all instances of that group. This makes modifying your building model much easier because you can change several instances of a group in one operation.
|
||||
|
||||
**Code Region 10-9: Creating a Group**
|
||||
---
|
||||
|
||||
|
||||
public void MakeGroup(Document document)
|
||||
{
|
||||
Group group = null;
|
||||
UIDocument uidoc = new UIDocument(document);
|
||||
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
|
||||
|
||||
if (selectedIds.Count > 0)
|
||||
{
|
||||
// Group all selected elements
|
||||
group = document.Create.NewGroup(selectedIds);
|
||||
// Initially, the group has a generic name, such as Group 1\. It can be modified by changing the name of the group type as follows:
|
||||
// Change the default group name to a new name "MyGroup"
|
||||
group.GroupType.Name = "MyGroup";
|
||||
}
|
||||
}
|
||||
|
||||
There are three types of groups in Revit; Model Group, Detail Group, and Attached Detail Group. All are created using the NewGroup() method. The created Group's type depends on the Elements passed.
|
||||
|
||||
* If no detail Element is passed, a Model Group is created.
|
||||
* If all Elements are detail elements, then a Detail Group is created.
|
||||
* If both types of Elements are included, a Model Group that contains an Attached Detail Group is created and returned.
|
||||
|
||||
|
||||
|
||||
Note: When elements are grouped, they can be deleted from the project.
|
||||
|
||||
* When a model element in a model group is deleted, it is still visible when the mouse cursor hovers over or clicks the group, even if the application returns Succeeded to the UI. In fact, the model element is deleted and you cannot select or access that element.
|
||||
* When the last member of a group instance is deleted, excluded, or removed from the project, the model group instance is deleted.
|
||||
|
||||
|
||||
|
||||
When elements are grouped, they cannot be moved or rotated. If you perform these operations on the grouped elements, nothing happens to the elements, though the Move() or Rotate() method returns true.
|
||||
|
||||
You cannot group dimensions and tags without grouping the elements they reference. If you do, the API call will fail.
|
||||
|
||||
You can group dimensions and tags that refer to model elements in a model group. The dimensions and tags are added to an attached detail group. The attached detail group cannot be moved, copied, rotated, arrayed, or mirrored without doing the same to the parent group.
|
||||
|
||||
## Attached Detail Groups
|
||||
|
||||
To determine if a group is an attached detail group, use the `Group.IsAttached` property. To find the group to which a detail group is attached, use the `Group.AttachedParentId` property.
|
||||
|
||||
If a Model Group has attached detail groups, the visibility of these detail groups can be controlled with:
|
||||
|
||||
* Group.ShowAttachedDetailGroups()
|
||||
* Group.ShowAllAttachedDetailGroups()
|
||||
* Group.HideAttachedDetailGroups()
|
||||
* Group.HideAllAttachedDetailGroups()
|
||||
|
||||
|
||||
|
||||
The attached detail groups available for a group or group type can be found with:
|
||||
|
||||
* Group.GetAvailableAttachedDetailGroupTypeIds()
|
||||
* GroupType.GetAvailableAttachedDetailGroupTypeIds()
|
||||
|
||||
|
||||
|
||||
`Group.IsCompatibleAttachedDetailGroupType()` checks if the orientation of an attached detail group matches the orientation of a view. To prevent displaying detail groups in the wrong view, verify that the OwnerViewId of a detail group matches the view in which you are trying to display it.
|
||||
|
||||
## Loading Groups from File
|
||||
|
||||
The `GroupLoadOptions` class provides options for loading a Revit group from file.
|
||||
|
||||
It has the following properties:
|
||||
|
||||
* `ReplaceDuplicatedGroups` \- If there are groups with the same names in source and destination documents set this property to true to replace existing groups, otherwise the operation will be canceled. The default value is false.
|
||||
|
||||
* `IncludeGrids` \- Returns true if grids should be brought in from the input file, false otherwise.
|
||||
|
||||
* `IncludeLevels` \- Returns true if levels should be brought in from the input file, false otherwise.
|
||||
|
||||
* `IncludeAttachedDetails` \- Returns true if attached detail groups should be included, false otherwise.
|
||||
|
||||
The methods `GroupLoadOptions.GetDuplicateTypeNamesHandler()` and `GroupLoadOptions.SetDuplicateTypeNamesHandler(IDuplicateTypeNamesHandler)` allow you to set or retrieve a duplicate type names handler. If this value is not set, the default handler is used.
|
||||
|
||||
|
||||
|
||||
|
||||
`GroupType.LoadFrom(string, GroupLoadOptions)` allows a group type to be replaced with the contents of the input file.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,43 @@
|
||||
# Mirroring Elements
|
||||
|
||||
# Mirroring Elements
|
||||
|
||||
The ElementTransformUtils class provides two static methods to mirror one or more elements in the project.
|
||||
|
||||
**Table 21: Mirror Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`MirrorElement(Document, ElementId, Plane)` | Mirror one element about a geometric plane.
|
||||
`MirrorElements(Document, ICollection<ElementId>, Plane, Boolean)` | Mirror several elements about a geometric plane. Can be performed on original geometry or a copy.
|
||||
|
||||
After performing the mirror operation, you can access the new elements from the Selection ElementSet.
|
||||
|
||||
ElementTransformUtils.CanMirrorElement() and ElementTransformUtils.CanMirrorElements() can be used to determine if one or more elements can be mirrored prior to attempting to mirror an element.
|
||||
|
||||
The following code illustrates how to mirror a wall using a plane calculated based on a side face of the wall.
|
||||
|
||||
**Code Region 10-8: Mirroring a wall**
|
||||
---
|
||||
|
||||
|
||||
public void MirrorWall(Autodesk.Revit.DB.Document document, Wall wall)
|
||||
{
|
||||
Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First();
|
||||
|
||||
// get one of the wall's major side faces
|
||||
Face face = wall.GetGeometryObjectFromReference(reference) as Face;
|
||||
|
||||
UV bboxMin = face.GetBoundingBox().Min;
|
||||
// create a plane based on this side face with an offset of 10 in the X & Y directions
|
||||
|
||||
Plane plane = Plane.CreateByNormalAndOrigin(face.ComputeNormal(bboxMin),
|
||||
face.Evaluate(bboxMin).Add(new XYZ(10, 10, 0)));
|
||||
|
||||
ElementTransformUtils.MirrorElement(document, wall.Id, plane);
|
||||
}
|
||||
|
||||
Every FamilyInstance has a Mirrored property. It indicates whether a FamilyInstance (for example a column) is mirrored.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,115 @@
|
||||
# Moving Elements
|
||||
|
||||
# Moving Elements
|
||||
|
||||
The ElementTransformUtils class provides two static methods to move one or more elements from one place to another.
|
||||
|
||||
**Table 19: Move Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`MoveElement( Document, ElementId, XYZ)` | Move an element in the document by a specified vector.
|
||||
`MoveElements(Document, ICollection<ElementId>, XYZ)` | Move several elements by a set of IDs in the document by a specified vector.
|
||||
|
||||
Note: When you use the MoveElement() or MoveElements() methods, the following rules apply.
|
||||
|
||||
* The methods cannot move a level-based element up or down from the level. When the element is level-based, you cannot change the Z coordinate value. However, you can place the element at any location in the same level. As well, some level based elements have an offset instance parameter you can use to move them in the Z direction.For example, if you create a new column at the original location (0, 0, 0) in Level1, and then move it to the new location (10, 20, 30), the column is placed at the location (10, 20, 0) instead of (10, 20, 30).
|
||||
|
||||
**Code Region 10-1: Using MoveElement()**
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
public void MoveColumn(Autodesk.Revit.DB.Document document, FamilyInstance column)
|
||||
{
|
||||
// get the column current location
|
||||
LocationPoint columnLocation = column.Location as LocationPoint;
|
||||
|
||||
XYZ oldPlace = columnLocation.Point;
|
||||
|
||||
// Move the column to new location.
|
||||
XYZ newPlace = new XYZ(10, 20, 30);
|
||||
ElementTransformUtils.MoveElement(document, column.Id, newPlace);
|
||||
|
||||
// now get the column's new location
|
||||
columnLocation = column.Location as LocationPoint;
|
||||
XYZ newActual = columnLocation.Point;
|
||||
|
||||
string info = "Original Z location: " + oldPlace.Z +
|
||||
"\nNew Z location: " + newActual.Z;
|
||||
|
||||
TaskDialog.Show("Revit",info);
|
||||
}
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
* When you move one or more elements, associated elements are moved. For example, if a wall with windows is moved, the windows are also moved.
|
||||
* [Pinned Elements](./Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Pinned_Elements_html.html) cannot be moved.
|
||||
|
||||
|
||||
|
||||
Another way to move an element in Revit is to use Location and its derivative objects. In the Revit Platform API, the Location object provides the ability to translate and rotate elements. More location information and control is available using the Location object derivatives such as LocationPoint or LocationCurve. If the Location element is downcast to a LocationCurve object or a LocationPoint object, move the curve or the point to a new place directly.
|
||||
|
||||
**Code Region 10-2: Moving using Location**
|
||||
---
|
||||
|
||||
|
||||
bool MoveUsingLocationCurve(Autodesk.Revit.ApplicationServices.Application application, Wall wall)
|
||||
{
|
||||
LocationCurve wallLine = wall.Location as LocationCurve;
|
||||
XYZ translationVec = new XYZ(10, 20, 0);
|
||||
return (wallLine.Move(translationVec));
|
||||
}
|
||||
|
||||
When you move the element, note that the vector (10, 20, 0) is not the destination but the offset. The following picture illustrates the wall position before and after moving.
|
||||
|
||||
**Figure 30: Move a wall using the LocationCurve**
|
||||
|
||||
In addition, you can use the LocationCurve Curve property or the LocationPoint Point property to move one element in Revit.
|
||||
|
||||
Use the Curve property to move a curve-driven element to any specified position. Many elements are curve-driven, such as walls, beams, and braces. Also use the property to resize the length of the element.
|
||||
|
||||
**Code Region 10-3: Moving using Curve**
|
||||
---
|
||||
|
||||
|
||||
void MoveUsingCurveParam(Autodesk.Revit.ApplicationServices.Application application, Wall wall)
|
||||
{
|
||||
LocationCurve wallLine = wall.Location as LocationCurve;
|
||||
XYZ p1 = XYZ.Zero;
|
||||
XYZ p2 = new XYZ(10, 20, 0);
|
||||
Line newWallLine = Line.CreateBound(p1, p2);
|
||||
|
||||
// Change the wall line to a new line.
|
||||
wallLine.Curve = newWallLine;
|
||||
}
|
||||
|
||||
You can also get or set a curve-based element's join properties with the LocationCurve.JoinType property.
|
||||
|
||||
Use the LocationPoint Point property to set the element's physical location.
|
||||
|
||||
**Code Region 10-4: Moving using Point**
|
||||
---
|
||||
|
||||
|
||||
void LocationMove(FamilyInstance column)
|
||||
{
|
||||
LocationPoint columnPoint = column.Location as LocationPoint;
|
||||
if (null != columnPoint)
|
||||
{
|
||||
XYZ newLocation = new XYZ(10, 20, 0);
|
||||
// Move the column to the new location
|
||||
columnPoint.Point = newLocation;
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,9 @@
|
||||
# Pinned Elements
|
||||
|
||||
# Pinned Elements
|
||||
|
||||
Elements can be pinned to prevent them from moving. The Element.Pinned property can be used to check if an Element is pinned or to pin or unpin an element.
|
||||
|
||||
When Element.Pinned is set to true, the element cannot be moved or rotated.
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,79 @@
|
||||
# Rotating Elements
|
||||
|
||||
# Rotating Elements
|
||||
|
||||
The ElementTransformUtils class provides two static methods to rotate one or several elements in the project.
|
||||
|
||||
**Table 20: Rotate Methods**
|
||||
|
||||
|
|
||||
---|---
|
||||
Member | Description
|
||||
`RotateElement(Document, ElementId, Line, double)` | Rotate an element in the document by a specified number of radians around a given axis.
|
||||
`RotateElements(Document, ICollection<ElementId>, Line, double)` | Rotate several elements by IDs in the project by a specified number of radians around a given axis.
|
||||
|
||||
In these methods, the angle of rotation is in radians. The positive radian means rotating counterclockwise around the specified axis, while the negative radian means clockwise, as the following pictures illustrates.
|
||||
|
||||
**Figure 31: Counterclockwise rotation**
|
||||
|
||||
**Figure 32: Clockwise rotation**
|
||||
|
||||
Note that pinned elements cannot be rotated.
|
||||
|
||||
**Code Region 10-5: Using RotateElement()**
|
||||
---
|
||||
|
||||
|
||||
public void RotateColumn(Autodesk.Revit.DB.Document document, Autodesk.Revit.DB.Element element)
|
||||
{
|
||||
XYZ point1 = new XYZ(10, 20, 0);
|
||||
XYZ point2 = new XYZ(10, 20, 30);
|
||||
// The axis should be a bound line.
|
||||
Line axis = Line.CreateBound(point1, point2);
|
||||
ElementTransformUtils.RotateElement(document, element.Id, axis, Math.PI / 3.0);
|
||||
}
|
||||
|
||||
If the element Location can be downcast to a LocationCurve or a LocationPoint, you can rotate the curve or the point directly.
|
||||
|
||||
**Code Region 10-6: Rotating based on location curve**
|
||||
---
|
||||
|
||||
|
||||
bool LocationRotate(Autodesk.Revit.ApplicationServices.Application application, Autodesk.Revit.DB.Element element)
|
||||
{
|
||||
bool rotated = false;
|
||||
// Rotate the element via its location curve.
|
||||
LocationCurve curve = element.Location as LocationCurve;
|
||||
if (null != curve)
|
||||
{
|
||||
Curve line = curve.Curve;
|
||||
XYZ aa = line.GetEndPoint(0);
|
||||
XYZ cc = new XYZ(aa.X, aa.Y, aa.Z + 10);
|
||||
Line axis = Line.CreateBound(aa, cc);
|
||||
rotated = curve.Rotate(axis, Math.PI / 2.0);
|
||||
}
|
||||
|
||||
return rotated;
|
||||
}
|
||||
|
||||
**Code Region 10-7: Rotating based on location point**
|
||||
---
|
||||
|
||||
|
||||
bool LocationPointRotate(Autodesk.Revit.ApplicationServices.Application application, Element element)
|
||||
{
|
||||
bool rotated = false;
|
||||
LocationPoint location = element.Location as LocationPoint;
|
||||
|
||||
if (null != location)
|
||||
{
|
||||
XYZ aa = location.Point;
|
||||
XYZ cc = new XYZ(aa.X, aa.Y, aa.Z + 10);
|
||||
Line axis = Line.CreateBound(aa, cc);
|
||||
rotated = location.Rotate(axis, Math.PI / 2.0);
|
||||
}
|
||||
|
||||
return rotated;
|
||||
}
|
||||
|
||||
**Parent page:** [Editing Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html)
|
||||
@@ -0,0 +1,21 @@
|
||||
# Editing Elements
|
||||
|
||||
# Editing Elements
|
||||
|
||||
In Revit, you can move, copy, rotate, align, delete, mirror, group, and array one element or a set of elements with the Revit Platform API. Using the editing functionality in the API is similar to the commands in the Revit UI.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Moving Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Moving_Elements_html.html)
|
||||
* [Copying Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Copying_Elements_html.html)
|
||||
* [Rotating Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Rotating_elements_html.html)
|
||||
* [Aligning Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Aligning_Elements_html.html)
|
||||
* [Mirroring Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Mirroring_Elements_html.html)
|
||||
* [Grouping Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Grouping_Elements_html.html)
|
||||
* [Creating Arrays of Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Creating_Arrays_of_Elements_html.html)
|
||||
* [Deleting Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Deleting_Elements_html.html)
|
||||
* [Pinned Elements](Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Pinned_Elements_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,296 @@
|
||||
# Applying Filters
|
||||
|
||||
# Applying Filters
|
||||
|
||||
Filters can be applied to a FilteredElementCollector using ElementFilters. An ElementFilter is a class that examines an element to see if it meets a certain criteria. The ElementFilter base class has three derived classes that divide element filters into three categories.
|
||||
|
||||
* **ElementQuickFilter** \- Quick filters operate only on the ElementRecord, a low-memory class which has a limited interface to read element properties. Elements which are rejected by a quick filter will not be expanded in memory.
|
||||
* **ElementSlowFilter** \- Slow filters require that the Element be obtained and expanded in memory first. Thus it is preferable to couple slow filters with at least one ElementQuickFilter, which should minimize the number of Elements that are expanded in order to evaluate against the criteria set by this filter.
|
||||
* **ElementLogicalFilter** \- Logical filters combine two or more filters logically. The component filters may be reordered by Revit to cause the quickest acting filters to be evaluated first.
|
||||
|
||||
|
||||
|
||||
Most filters may be inverted using an overload constructor that takes a Boolean argument indicating to invert the filter so that elements that would normally be accepted by the filter will be rejected, and elements that would normally be rejected will be accepted. Filters that cannot be inverted are noted in their corresponding sections below.
|
||||
|
||||
There is a set of predefined filters available for common uses. Many of these built-in filters provide the basis for the FilteredElementCollector shortcut methods mentioned in the FilteredElementCollector section above. The next three sections provide more information on the built-in filters.
|
||||
|
||||
Once a filter is created, it needs to be applied to the FilteredElementCollector. The generic method WherePasses() is used to apply a single ElementFilter to the FilteredElementCollector.
|
||||
|
||||
Filters can also be applied using a number of shortcut methods provided by FilteredElementCollector. Some apply a specific filter without further input, such as WhereElementIsCurveDriven(), while others apply a specific filter with a simple piece of input, such as the OfCategory() method which takes a BuiltInCategory as a parameter. And lastly there are methods such as UnionWith() that join filters together. All of these methods return the same collector allowing filters to be easily chained together.
|
||||
|
||||
### Quick filters
|
||||
|
||||
Quick filters operate only on the ElementRecord, a low-memory class which has a limited interface to read element properties. Elements which are rejected by a quick filter will not be expanded in memory. The following table summarizes the built-in quick filters, and some examples follow for a few of the filters.
|
||||
|
||||
**Table 13: Built-in Quick Filters**
|
||||
|
||||
**Built-in Filter** | **What it passes** | **Shortcut Method(s)**
|
||||
---|---|---
|
||||
BoundingBoxContainsPointFilter | Elements which have a bounding box that contains a given point | None
|
||||
BoundingBoxIntersectsFilter | Elements which have a bounding box which intersects a given outline | None
|
||||
BoundingBoxIsInsideFilter | Elements which have a bounding box inside a given outline | None
|
||||
ElementCategoryFilter | Elements matching the input category id | OfCategoryId()
|
||||
ElementClassFilter | Elements matching the input runtime class (or derived classes) | OfClass()
|
||||
ElementDesignOptionFilter | Elements in a particular design option | ContainedInDesignOption()
|
||||
ElementIdSetFilter | Elements whose ElementIds are included in a collection
|
||||
ElementIsCurveDrivenFilter | Elements which are curve driven | WhereElementIsCurveDriven()
|
||||
ElementIsElementTypeFilter | Elements which are "Element types" | WhereElementIsElementType() WhereElementIsNotElementType()
|
||||
ElementMulticategoryFilter | Elements matching any of a given set of categories | None
|
||||
ElementMulticlassFilter | Elements matching a given set of classes (or derived classes) | None
|
||||
ElementOwnerViewFilter | Elements which are view-specific | OwnedByView() WhereElementIsViewIndependent()
|
||||
ElementStructuralTypeFilter | Elements matching a given structural type | None
|
||||
ExclusionFilter | All elements except the element ids input to the filter | Excluding()
|
||||
FamilySymbolFilter | Symbols of a particular family |
|
||||
VisibleInViewFilter | Elements that are most likely visible in the given view |
|
||||
|
||||
Note: The FamilySymbolFilter cannot be inverted.
|
||||
|
||||
Note: The bounding box filters exclude all objects derived from View and objects derived from ElementType.
|
||||
|
||||
The following example creates an outline in the document and then uses a BoundingBoxIntersectsFilter to find the elements in the document with a bounding box that intersects that outline. It then shows how to use an inverted filter to find all walls whose bounding box do not intersect the given outline. Note that the use of the OfClass() method applies an ElementClassFilter to the collection as well.
|
||||
|
||||
**Code Region 6-2: BoundingBoxIntersectsFilter example**
|
||||
---
|
||||
|
||||
|
||||
public void IntersectsFilterSample(Document document)
|
||||
{
|
||||
// Use BoundingBoxIntersects filter to find elements with a bounding box that intersects the given Outline in the document.
|
||||
|
||||
// Create a Outline, uses a minimum and maximum XYZ point to initialize the outline.
|
||||
Outline myOutLn = new Outline(new XYZ(0, 0, 0), new XYZ(100, 100, 100));
|
||||
|
||||
// Create a BoundingBoxIntersects filter with this Outline
|
||||
BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(myOutLn);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
// This filter excludes all objects derived from View and objects derived from ElementType
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
IList<Element> elements = collector.WherePasses(filter).ToElements();
|
||||
|
||||
// Find all walls which don't intersect with BoundingBox: use an inverted filter to match elements
|
||||
// Use shortcut command OfClass() to find walls only
|
||||
BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(myOutLn, true);
|
||||
collector = new FilteredElementCollector(document);
|
||||
IList<Element> notIntersectWalls = collector.OfClass(typeof(Wall)).WherePasses(invertFilter).ToElements();
|
||||
}
|
||||
|
||||
The next example uses an exclusion filter to find all walls that are not currently selected in the document.
|
||||
|
||||
**Code Region 6-3: Creating an exclusion filter**
|
||||
---
|
||||
|
||||
|
||||
public void FindNotSelectedWalls(UIDocument uiDocument)
|
||||
{
|
||||
// Find all walls that are not currently selected,
|
||||
// Get all element ids which are current selected by users, exclude these ids when filtering
|
||||
ICollection<ElementId> selectedIds = uiDocument.Selection.GetElementIds();
|
||||
|
||||
// Use the selection to instantiate an exclusion filter
|
||||
ExclusionFilter filter = new ExclusionFilter(selectedIds);
|
||||
// For the sake of simplicity we do not test here whether the selection is empty or not,
|
||||
// but in production code a proper validation would have to be done to avoid an argument
|
||||
// exception from the filter's consructor.
|
||||
|
||||
// Apply the filter to the elements in the active document,
|
||||
// Use shortcut method OfClass() to find Walls only
|
||||
FilteredElementCollector collector = new FilteredElementCollector(uiDocument.Document);
|
||||
IList<Element> walls = collector.WherePasses(filter).OfClass(typeof(Wall)).ToElements();
|
||||
}
|
||||
|
||||
Note: The ElementClassFilter will match elements whose class is an exact match to the input class, or elements whose class is derived from the input class. The following example uses an ElementClassFilter to get all loads in the document.
|
||||
|
||||
**Code Region 6-4: Using an ElementClassFilter to get loads**
|
||||
---
|
||||
|
||||
|
||||
public void MakeLoadFilter(Document document)
|
||||
{
|
||||
// Use ElementClassFilter to find all loads in the document
|
||||
// Using typeof(LoadBase) will yield all AreaLoad, LineLoad and PointLoad
|
||||
ElementClassFilter filter = new ElementClassFilter(typeof(LoadBase));
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
ICollection<Element> allLoads = collector.WherePasses(filter).ToElements();
|
||||
}
|
||||
|
||||
There is a small subset of Element subclasses in the API which are not supported by the element class filter. These types exist in the API, but not in Revit's native object model, which means that this filter doesn't support them. In order to use a class filter to find elements of these types, it is necessary to use a higher level class and then process the results further to find elements matching only the subtype.
|
||||
|
||||
Note: Dedicated filters exist for some of these types.
|
||||
|
||||
The following types are affected by this restriction:
|
||||
|
||||
**Type** | **Dedicated Filter**
|
||||
---|---
|
||||
Subclasses of Autodesk.Revit.DB.Material | None
|
||||
Subclasses of Autodesk.Revit.DB.CurveElement | CurveElementFilter
|
||||
Subclasses of Autodesk.Revit.DB.ConnectorElement | None
|
||||
Subclasses of Autodesk.Revit.DB.HostedSweep | None
|
||||
Autodesk.Revit.DB.Architecture.Room | RoomFilter
|
||||
Autodesk.Revit.DB.Mechanical.Space | SpaceFilter
|
||||
Autodesk.Revit.DB.Area | AreaFilter
|
||||
Autodesk.Revit.DB.Architecture.RoomTag | RoomTagFilter
|
||||
Autodesk.Revit.DB.Mechanical.SpaceTag | SpaceTagFilter
|
||||
Autodesk.Revit.DB.AreaTag | AreaTagFilter
|
||||
Autodesk.Revit.DB.CombinableElement | None
|
||||
Autodesk.Revit.DB.Mullion | None
|
||||
Autodesk.Revit.DB.Panel | None
|
||||
Autodesk.Revit.DB.AnnotationSymbol | None
|
||||
Autodesk.Revit.DB.Structure.AreaReinforcementType | None
|
||||
Autodesk.Revit.DB.Structure.PathReinforcementType | None
|
||||
Autodesk.Revit.DB.AnnotationSymbolType | None
|
||||
Autodesk.Revit.DB.Architecture.RoomTagType | None
|
||||
Autodesk.Revit.DB.Mechanical.SpaceTagType | None
|
||||
Autodesk.Revit.DB.AreaTagType | None
|
||||
Autodesk.Revit.DB.Structure.TrussType | None
|
||||
|
||||
### Slow Filters
|
||||
|
||||
Slow filters require that the Element be obtained and expanded in memory first. Thus it is preferable to couple slow filters with at least one ElementQuickFilter, which should minimize the number of Elements that are expanded in order to evaluate against the criteria set by this filter. The following table summarizes the built-in slow filters, while a few examples follow to provide an in-depth look at some of the filters.
|
||||
|
||||
**Table 14: Built-in Slow Filters**
|
||||
|
||||
**Built-in Filter** | **What it passes** | **Shortcut Method(s)**
|
||||
---|---|---
|
||||
AreaFilter | Areas | None
|
||||
AreaTagFilter | Area tags | None
|
||||
CurveElementFilter | CurveElements | None
|
||||
ElementLevelFilter | Elements associated with a given level id | None
|
||||
ElementParameterFilter | Elements passing one or more parameter filter rules | None
|
||||
ElementPhaseStatusFilter | Elements with a given phase status on a given phase | None
|
||||
FamilyInstanceFilter | Instances of a particular family instance | None
|
||||
FamilyStructuralMaterialTypeFilter | Family elements of given structural material type | None
|
||||
PrimaryDesignOptionMemberFilter | Elements owned by any primary design option | None
|
||||
RoomFilter | Rooms | None
|
||||
RoomTagFilter | Room tags | None
|
||||
SpaceFilter | Spaces | None
|
||||
SpaceTagFilter | Space tags | None
|
||||
StructuralInstanceUsageFilter | FamilyInstances of given structural usage | None
|
||||
StructuralMaterialTypeFilter | FamilyInstances of given structural material type | None
|
||||
StructuralWallUsageFilter | Walls of given structural wall usage | None
|
||||
[Element Intersection Filters](./Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Element_Intersection_Filters_html.html) | Elements that intersect the solid geometry of a given element | None
|
||||
[Element Intersection Filters>](./Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Element_Intersection_Filters_html.html) | Elements that intersect the given solid geometry | None
|
||||
|
||||
The following slow filters cannot be inverted:
|
||||
|
||||
* RoomFilter
|
||||
* RoomTagFilter
|
||||
* AreaFilter
|
||||
* AreaTagFilter
|
||||
* SpaceFilter
|
||||
* SpaceTagFilter
|
||||
* FamilyInstanceFilter
|
||||
|
||||
|
||||
|
||||
As mentioned in the quick filters section, some classes do not work with the ElementClassFilter. Some of those classes, such as Room and RoomTag have their own dedicated filters.
|
||||
|
||||
**Code Region 6-5: Using the Room filter**
|
||||
---
|
||||
|
||||
|
||||
public void MakeRoomFilter(Document document)
|
||||
{
|
||||
// Use a RoomFilter to find all room elements in the document. It is necessary to use the RoomFilter and not an ElementClassFilter or the shortcut method OfClass() because the Room class is not supported by those methods.
|
||||
RoomFilter filter = new RoomFilter();
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
IList<Element> rooms = collector.WherePasses(filter).ToElements();
|
||||
}
|
||||
|
||||
The ElementParameterFilter is a powerful filter that can find elements based on values of parameters they may have. It can find elements whose parameter values match a specific value or are greater or less than some value. ElementParameterFilter can also be used to find elements that support a specific shared parameter.
|
||||
|
||||
The example below uses an ElementParameterFilter to find rooms whose size is more than 100 square feet and rooms with less than 100 square feet.
|
||||
|
||||
**Code Region 6-6: Using a parameter filter**
|
||||
---
|
||||
|
||||
|
||||
public void FindRooms(Document document)
|
||||
{
|
||||
// Creates an ElementParameter filter to find rooms whose area is greater than specified value
|
||||
// Create filter by provider and evaluator
|
||||
BuiltInParameter areaParam = BuiltInParameter.ROOM_AREA;
|
||||
// provider
|
||||
ParameterValueProvider pvp = new ParameterValueProvider(new ElementId((long)areaParam));
|
||||
|
||||
// Create an ElementParameter filter to filter rooms whose area is greater than 100 SF
|
||||
var ruleGreater100 = new FilterDoubleRule(pvp, new FilterNumericGreater(), 100, 1E-6);
|
||||
ElementParameterFilter filterGreater100 = new ElementParameterFilter(ruleGreater100);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
IList<Element> roomsGreater100 = new FilteredElementCollector(document)
|
||||
.OfCategory(BuiltInCategory.OST_Rooms)
|
||||
.WherePasses(filterGreater100).ToElements();
|
||||
|
||||
// Find rooms whose area is less than or equal to 100:
|
||||
// Use inverted filter to match elements
|
||||
ElementParameterFilter filterLessthan100 = new ElementParameterFilter(ruleGreater100, true);
|
||||
IList<Element> roomsLessthan100 = new FilteredElementCollector(document)
|
||||
.OfCategory(BuiltInCategory.OST_Rooms)
|
||||
.WherePasses(filterLessthan100).ToElements();
|
||||
}
|
||||
|
||||
The following example shows how to use the FamilyStructuralMaterialTypeFilter to find all families whose material type is wood. It also shows how to use an inverted filter to find all families whose material type is not wood.
|
||||
|
||||
**Code Region 6-7: Find all families with wood material**
|
||||
---
|
||||
|
||||
|
||||
public void FindWoodFamilies(Document document)
|
||||
{
|
||||
// Use FamilyStructuralMaterialType filter to find families whose material type is Wood
|
||||
FamilyStructuralMaterialTypeFilter filter = new FamilyStructuralMaterialTypeFilter(StructuralMaterialType.Wood);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
ICollection<Element> woodFamiles = collector.WherePasses(filter).ToElements();
|
||||
|
||||
// Find families are not Wood: Use inverted filter to match families
|
||||
FamilyStructuralMaterialTypeFilter notWoodFilter =
|
||||
new FamilyStructuralMaterialTypeFilter(StructuralMaterialType.Wood, true);
|
||||
collector = new FilteredElementCollector(document);
|
||||
ICollection<Element> notWoodFamilies = collector.WherePasses(notWoodFilter).ToElements();
|
||||
}
|
||||
|
||||
The last two slow filters derive from ElementIntersectsFilter which is a base class for filters used to match elements which intersect with geometry. See Code Region: Find Nearby Walls in the section [Geometry Utility Classes](../../Revit_Geometric_Elements/Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Utility_Classes_html.html) for an example of the use of this type of filter.
|
||||
|
||||
### Logical filters
|
||||
|
||||
Logical filters combine two or more filters logically. The following table summarizes the built-in logical filters.
|
||||
|
||||
**Table 15: Built-in Logical Filters**
|
||||
|
||||
**Built-in Filter** | **What it passes** | **Shortcut Method(s)**
|
||||
---|---|---
|
||||
LogicalAndFilter | Elements that pass 2 or more filters | WherePasses()- adds one additional filter IntersectWith() - joins two sets of independent filters
|
||||
LogicalOrFilter | Elements that pass at least one of 2 or more filters | UnionWith() - joins two sets of independent filters
|
||||
|
||||
In the example below, two quick filters are combined using a logical filter to get all door FamilyInstance elements in the document.
|
||||
|
||||
**Code Region 6-8: Using LogicalAndFilter to find all door instances**
|
||||
---
|
||||
|
||||
|
||||
public void FindDoors(Document document)
|
||||
{
|
||||
// Find all door instances in the project by finding all elements that both belong to the door category and are family instances.
|
||||
ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));
|
||||
|
||||
// Create a category filter for Doors
|
||||
ElementCategoryFilter doorsCategoryfilter =
|
||||
new ElementCategoryFilter(BuiltInCategory.OST_Doors);
|
||||
|
||||
// Create a logic And filter for all Door FamilyInstances
|
||||
LogicalAndFilter doorInstancesFilter = new LogicalAndFilter(familyInstanceFilter,
|
||||
doorsCategoryfilter);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
IList<Element> doors = collector.WherePasses(doorInstancesFilter).ToElements();
|
||||
}
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,19 @@
|
||||
# Bounding Box Filters
|
||||
|
||||
# Bounding Box Filters
|
||||
|
||||
The BoundingBox filters:
|
||||
|
||||
* BoundingBoxIsInsideFilter
|
||||
* BoundingBoxIntersectsFilter
|
||||
* BoundingBoxContainsPointFilter
|
||||
|
||||
|
||||
|
||||
help you find elements whose bounding boxes meet a certain criteria. You can check if each element’s bounding box is inside a given volume, intersects a given volume, or contains a given point. You can also reverse this check to find elements which do not intersect a volume or contain a given point.
|
||||
|
||||
BoundingBox filters use Outline as their inputs. Outline is a class representing a right rectangular prism whose axes are aligned to the Revit world coordinate system.
|
||||
|
||||
These filters work best for shapes whose actual geometry matches closely the geometry of its bounding box. Examples might include linear walls whose curve aligns with the X or Y direction, rectangular rooms formed by such walls, floors or roofs aligned to such walls, or reasonably rectangular families. Otherwise, there is the potential for false positives as the bounding box of the element may be much bigger than the actual geometry. (In these cases, you can use the actual element’s geometry to determine if the element really meets the criteria.)
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,17 @@
|
||||
# Create a FilteredElementCollector
|
||||
|
||||
# Create a FilteredElementCollector
|
||||
|
||||
The main class used for element iteration and filtering is called FilteredElementCollector. It is constructed in one of three ways:
|
||||
|
||||
1. From a document - will search and filter the set of elements in a document.
|
||||
2. From a document and set of ElementIds - will search and filter a specified set of elements.
|
||||
3. From a document and a view - will search and filter the visible elements in a view.
|
||||
|
||||
|
||||
|
||||
Note: Always check that a view is valid for element iteration when filtering elements in a specified view by using the static FilteredElementCollector.IsViewValidForElementIteration().
|
||||
|
||||
When the object is first created, there are no filters applied. This class requires that at least one condition be set before making at attempt to access the elements, otherwise an exception will be thrown.
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,65 @@
|
||||
# Element Intersection Filters
|
||||
|
||||
# Element Intersection Filters
|
||||
|
||||
The element filters:
|
||||
|
||||
* ElementIntersectsElementFilter
|
||||
* ElementIntersectsSolidFilter
|
||||
|
||||
|
||||
|
||||
pass elements whose actual 3D geometry intersects the 3D geometry of the target object.
|
||||
|
||||
With ElementIntersectsElementFilter, the target object is another element. The intersection is determined with the same logic used by Revit to determine if an interference exists during generation of an Interference Report. (This means that some combinations of elements will never pass this filter, such as concrete members which are automatically joined at their intersections, or site elements which are also excluded from interference checks.) Also, elements which have no solid geometry, such as Rebar, will not pass this filter.
|
||||
|
||||
With ElementIntersectsSolidFilter, the target object is any solid. This solid could have been obtained from an existing element, created from scratch using the routines in GeometryCreationUtilities, or the result of a secondary operation such as a Boolean operation. Similar to the ElementIntersectsElementFilter, this filter will not pass elements which lack solid geometry.
|
||||
|
||||
Both filters can be inverted to match elements outside the target object volume.
|
||||
|
||||
Both filters are slow filters, and thus are best combined with one or more quick filters such as class or category filters.
|
||||
|
||||
**Code region: using ElementIntersectsSolidFilter to match elements which block disabled egress to doors**
|
||||
---
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds any Revit physical elements which interfere with the target
|
||||
/// solid region surrounding a door.</summary>
|
||||
/// <remarks>This routine is useful for detecting interferences which are
|
||||
/// violations of the Americans with Disabilities Act or other local disabled
|
||||
/// access codes.</remarks>
|
||||
/// <param name="doorInstance">The door instance.</param>
|
||||
/// <param name="doorAccessibilityRegion">The accessibility region calculated
|
||||
/// to surround the approach of the door.
|
||||
/// Because the geometric parameters of this region are code- and
|
||||
/// door-specific, calculation of the geometry of the region is not
|
||||
/// demonstrated in this example.</param>
|
||||
/// <returns>A collection of interfering element ids.</returns>
|
||||
private ICollection<ElementId> FindElementsInterferingWithDoor(FamilyInstance doorInstance, Solid doorAccessibilityRegion)
|
||||
{
|
||||
// Setup the filtered element collector for all document elements.
|
||||
FilteredElementCollector interferingCollector =
|
||||
new FilteredElementCollector(doorInstance.Document);
|
||||
|
||||
// Only accept element instances
|
||||
interferingCollector.WhereElementIsNotElementType();
|
||||
|
||||
// Exclude intersections with the door itself or the host wall for the door.
|
||||
List<ElementId> excludedElements = new List<ElementId>();
|
||||
excludedElements.Add(doorInstance.Id);
|
||||
excludedElements.Add(doorInstance.Host.Id);
|
||||
ExclusionFilter exclusionFilter = new ExclusionFilter(excludedElements);
|
||||
interferingCollector.WherePasses(exclusionFilter);
|
||||
|
||||
// Set up a filter which matches elements whose solid geometry intersects
|
||||
// with the accessibility region
|
||||
ElementIntersectsSolidFilter intersectionFilter =
|
||||
new ElementIntersectsSolidFilter(doorAccessibilityRegion);
|
||||
interferingCollector.WherePasses(intersectionFilter);
|
||||
|
||||
// Return all elements passing the collector
|
||||
return interferingCollector.ToElementIds();
|
||||
}
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,186 @@
|
||||
# Getting filtered elements or element ids
|
||||
|
||||
# Getting filtered elements or element ids
|
||||
|
||||
Once one or more filters have been applied to the FilteredElementCollector, the filtered set of elements can be retrieved in one of three ways:
|
||||
|
||||
1. Obtain a collection of Elements or ElementIds.
|
||||
* ToElements() - returns all elements that pass all applied filters
|
||||
* ToElementIds() - returns ElementIds of all elements which pass all applied filters
|
||||
2. Obtain the first Element or ElementId that matches the filter.
|
||||
* FirstElement() - returns first element to pass all applied filters
|
||||
* FirstElementId() - returns id of first element to pass all applied filters
|
||||
3. Obtain an ElementId or Element iterator.
|
||||
* GetElementIdIterator() - returns FilteredElementIdIterator to the element ids passing the filters
|
||||
* GetElementIterator() - returns FilteredElementIterator to the elements passing the filters
|
||||
* GetEnumerator() - returns an `IEnumerator<Element>` that iterates through collection of passing elements
|
||||
|
||||
|
||||
|
||||
You should only use one of the methods from these groups at a time; the collector will reset if you call another method to extract elements. Thus, if you have previously obtained an iterator, it will be stopped and traverse no more elements if you call another method to extract elements.
|
||||
|
||||
Which method is best depends on the application. If just one matching element is required, FirstElement() or FirstElementId() is the best choice. If all the matching elements are required, use ToElements(). If a variable number are needed, use an iterator.
|
||||
|
||||
If the application will be deleting elements or making significant changes to elements in the filtered list, ToElementIds() or an element id iterator are the best options. This is because deleting elements or making significant changes to an element can invalidate an element handle. With element ids, the call to Document.GetElement() with the ElementId will always return a valid Element (or a null reference if the element has been deleted).
|
||||
|
||||
Using the ToElements() method to get the filter results as a collection of elements allows for the use of foreach to examine each element in the set, as is shown below:
|
||||
|
||||
**Code Region 6-9: Using ToElements() to get filter results**
|
||||
---
|
||||
|
||||
|
||||
public void ToElementsSample(Document document)
|
||||
{
|
||||
// Use ElementClassFilter to find all loads in the document
|
||||
// Using typeof(LoadBase) will yield all AreaLoad, LineLoad and PointLoad
|
||||
ElementClassFilter filter = new ElementClassFilter(typeof(LoadBase));
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
collector.WherePasses(filter);
|
||||
ICollection<Element> allLoads = collector.ToElements();
|
||||
|
||||
String prompt = "The loads in the current document are:\n";
|
||||
foreach (Element loadElem in allLoads)
|
||||
{
|
||||
LoadBase load = loadElem as LoadBase;
|
||||
prompt += load.GetType().Name + ": " +
|
||||
load.Name + "\n";
|
||||
}
|
||||
|
||||
TaskDialog.Show("Revit", prompt);
|
||||
}
|
||||
|
||||
When just one passing element is needed, use FirstElement():
|
||||
|
||||
**Code Region 6-10: Get the first passing element**
|
||||
---
|
||||
|
||||
|
||||
public void GetFirstElement(Document document)
|
||||
{
|
||||
// Create a filter to find all columns
|
||||
StructuralInstanceUsageFilter columnFilter =
|
||||
new StructuralInstanceUsageFilter(StructuralInstanceUsage.Column);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
collector.WherePasses(columnFilter);
|
||||
|
||||
// Get the first column from the filtered results
|
||||
// Element will be a FamilyInstance
|
||||
FamilyInstance column = collector.FirstElement() as FamilyInstance;
|
||||
}
|
||||
|
||||
In some cases, FirstElement() is not sufficient. This next example shows how to use extension methods to get the first non-template 3D view (which is useful for input to the ReferenceIntersector constructors).
|
||||
|
||||
**Code Region 6-11: Get first passing element using extension methods**
|
||||
---
|
||||
|
||||
|
||||
public void UseExtensionMethods(Document document)
|
||||
{
|
||||
// Use filter to find a non-template 3D view
|
||||
// This example does not use FirstElement() since first filterd view3D might be a template
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
|
||||
|
||||
// apply ElementClassFilter
|
||||
collector.OfClass(typeof(View3D));
|
||||
|
||||
// use extension methods to get first non-template View3D
|
||||
View3D view3D = collector.Cast<View3D>().First<View3D>(isNotTemplate);
|
||||
}
|
||||
|
||||
The following example demonstrates the use of the FirstElementId() method to get one passing element (a 3d view in this case) and the use of ToElementIds() to get the filter results as a collection of element ids (in order to delete a set of elements in this case).
|
||||
|
||||
**Code Region 6-12: Using Getting filter results as element ids**
|
||||
---
|
||||
|
||||
|
||||
public void GetElementIds(Document document)
|
||||
{
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
|
||||
// Use shortcut OfClass to get View elements
|
||||
collector.OfClass(typeof(View3D));
|
||||
|
||||
// Get the Id of the first view
|
||||
ElementId viewId = collector.FirstElementId();
|
||||
|
||||
// Test if the view is valid for element filtering
|
||||
if (FilteredElementCollector.IsViewValidForElementIteration(document, viewId))
|
||||
{
|
||||
FilteredElementCollector viewCollector = new FilteredElementCollector(document, viewId);
|
||||
|
||||
// Get all FamilyInstance items in the view
|
||||
viewCollector.OfClass(typeof(FamilyInstance));
|
||||
ICollection<ElementId> familyInstanceIds = viewCollector.ToElementIds();
|
||||
|
||||
document.Delete(familyInstanceIds);
|
||||
}
|
||||
}
|
||||
|
||||
The GetElementIterator() method is used in the following example that iterates through the filtered elements to check the flow state of some pipes.
|
||||
|
||||
**Code Region 6-13: Getting the results as an element iterator**
|
||||
---
|
||||
|
||||
|
||||
public void GetIterator(Document document)
|
||||
{
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
|
||||
// Apply a filter to get all pipes in the document
|
||||
collector.OfClass(typeof(Autodesk.Revit.DB.Plumbing.Pipe));
|
||||
|
||||
// Get results as an element iterator and look for a pipe with
|
||||
// a specific flow state
|
||||
FilteredElementIterator elemItr = collector.GetElementIterator();
|
||||
elemItr.Reset();
|
||||
while (elemItr.MoveNext())
|
||||
{
|
||||
Pipe pipe = elemItr.Current as Pipe;
|
||||
if (pipe.FlowState == PipeFlowState.LaminarState)
|
||||
{
|
||||
TaskDialog.Show("Revit", "Model has at least one pipe with Laminar flow state.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Alternatively, the filter results can be returned as an element id iterator:
|
||||
|
||||
**Code Region 6-14: Getting the results as an element id iterator**
|
||||
---
|
||||
|
||||
|
||||
public void GetIdIterator(Document document)
|
||||
{
|
||||
// Use a RoomFilter to find all room elements in the document.
|
||||
RoomFilter filter = new RoomFilter();
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
collector.WherePasses(filter);
|
||||
|
||||
// Get results as ElementId iterator
|
||||
FilteredElementIdIterator roomIdItr = collector.GetElementIdIterator();
|
||||
roomIdItr.Reset();
|
||||
while (roomIdItr.MoveNext())
|
||||
{
|
||||
ElementId roomId = roomIdItr.Current;
|
||||
// Warn rooms smaller than 50 SF
|
||||
Room room = document.GetElement(roomId) as Room;
|
||||
if (room.Area < 50.0)
|
||||
{
|
||||
String prompt = "Room is too small: id = " + roomId.ToString();
|
||||
TaskDialog.Show("Revit", prompt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
In some cases, it may be useful to test a single element against a given filter, rather than getting all elements that pass the filter. There are two overloads for ElementFilter.PassesFilter() that test a given Element, or ElementId, against the filter, returning true if the element passes the filter.
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,32 @@
|
||||
# LINQ Queries
|
||||
|
||||
# LINQ Queries
|
||||
|
||||
In .NET, the FilteredElementCollector class supports the IEnumerable interface for Elements. You can use this class with LINQ queries and operations to process lists of elements. Note that because the ElementFilters and the shortcut methods offered by this class process elements in native code before their managed wrappers are generated, better performance will be obtained by using as many native filters as possible on the collector before attempting to process the results using LINQ queries.
|
||||
|
||||
The following example uses an ElementClassFilter to get all FamilyInstance elements in the document, and then uses a LINQ query to narrow down the results to those FamilyInstances with a specific name.
|
||||
|
||||
**Code Region 6-15: Using LINQ query**
|
||||
---
|
||||
|
||||
|
||||
public void LinqSample(Document document)
|
||||
{
|
||||
// Use ElementClassFilter to find family instances whose name is 60" x 30" Student
|
||||
ElementClassFilter filter = new ElementClassFilter(typeof(FamilyInstance));
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
collector.WherePasses(filter);
|
||||
|
||||
// Use Linq query to find family instances whose name is 60" x 30" Student
|
||||
var query = from element in collector
|
||||
where element.Name == "60\" x 30\" Student"
|
||||
select element;
|
||||
|
||||
// Cast found elements to family instances,
|
||||
// this cast to FamilyInstance is safe because ElementClassFilter for FamilyInstance was used
|
||||
List<FamilyInstance> familyInstances = query.Cast<FamilyInstance>().ToList<FamilyInstance>();
|
||||
}
|
||||
|
||||
**Parent page:** [Filtering](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_html.html)
|
||||
@@ -0,0 +1,49 @@
|
||||
# Filtering
|
||||
|
||||
# Filtering
|
||||
|
||||
The Revit API provides a mechanism for filtering and iterating elements in a Revit document. This is the best way to get a set of related elements, such as all walls or doors in the document. Filters can also be used to find a very specific set of elements, such as all beams of a specific size.
|
||||
|
||||
The basic steps to get elements passing a specified filter are as follows:
|
||||
|
||||
1. Create a new FilteredElementCollector.
|
||||
2. Apply one or more filters to it.
|
||||
3. Get filtered elements or element ids (using one of several methods).
|
||||
|
||||
|
||||
|
||||
The following sample covers the basic steps to filtering and iterating elements in the document.
|
||||
|
||||
**Code Region 6-1: Use element filtering to get all wall instances in document**
|
||||
---
|
||||
|
||||
|
||||
// Find all Wall instances in the document by using category filter
|
||||
public void GetAllWalls(Document document)
|
||||
{
|
||||
ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
|
||||
|
||||
// Apply the filter to the elements in the active document
|
||||
// Use shortcut WhereElementIsNotElementType() to find wall instances only
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
IList<Element> walls = collector.WherePasses(filter).WhereElementIsNotElementType().ToElements();
|
||||
String prompt = "The walls in the current document are:\n";
|
||||
foreach (Element e in walls)
|
||||
{
|
||||
prompt += e.Name + "\n";
|
||||
}
|
||||
TaskDialog.Show("Revit", prompt);
|
||||
}
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Create a FilteredElementCollector](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Create_a_FilteredElementCollector_html.html)
|
||||
* [Applying Filters](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Applying_Filters_html.html)
|
||||
* [Getting filtered elements or element ids](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Getting_filtered_elements_or_element_ids_html.html)
|
||||
* [LINQ Queries](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_LINQ_Queries_html.html)
|
||||
* [Bounding Box Filters](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Bounding_Box_filters_html.html)
|
||||
* [Element Intersection Filters](Filtering/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Filtering_Element_Intersection_Filters_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,32 @@
|
||||
# Built-In Parameters
|
||||
|
||||
# Built-In Parameters
|
||||
|
||||
The Revit Platform API has a large number of built-in parameters.
|
||||
|
||||
Built-in parameters are defined in the Autodesk.Revit.Parameters.BuiltInParameter enumeration (see the RevitAPI Help.chm file for the definition of this enumeration). This enumeration has generated documentation visible from Visual Studio intellisense as shown below. The documentation for each id includes the parameter name, as found in the Element Properties dialog in the English version of Autodesk Revit. Note that multiple distinct parameter ids may map to the same English name; in those cases you must examine the parameters associated with a specific element to determine which parameter id to use.
|
||||
|
||||
The parameter ID is used to retrieve the specific parameter from an element, if it exists, using the Element.Parameter property. However, not all parameters can be retrieved using the ID. For example, family parameters are not exposed in the Revit Platform API, therefore, you cannot get them using the built-in parameter ID.
|
||||
|
||||
The following code sample shows how to get the specific parameter using the BuiltInParameter Id:
|
||||
|
||||
**Code Region 8-3: Getting a parameter based on BuiltInParameter**
|
||||
---
|
||||
|
||||
|
||||
public Parameter FindWithBuiltinParameterID(Wall wall)
|
||||
{
|
||||
// Use the WALL_BASE_OFFSET paramametId
|
||||
// to get the base offset parameter of the wall.
|
||||
BuiltInParameter paraIndex = BuiltInParameter.WALL_BASE_OFFSET;
|
||||
Parameter parameter = wall.get_Parameter(paraIndex);
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
|
||||
## Getting localized parameter names
|
||||
|
||||
The method `LabelUtils.GetLabelFor Method (BuiltInParameter, LanguageType)` returns the localized string name for the built-in parameter. If the corresponding resource DLL cannot be found, the US-English name will be returned.
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,68 @@
|
||||
# Definition
|
||||
|
||||
# Definition
|
||||
|
||||
The Definition object describes the data type, name, and other Parameter details.
|
||||
|
||||
There are two kinds of definition objects derived from this object.
|
||||
|
||||
* InternalDefinition represents all kinds of definitions existing entirely in the Revit database.
|
||||
* ExternalDefinition represents definitions stored on disk in a shared parameter file.
|
||||
|
||||
|
||||
|
||||
You should write the code to use the Definition base class so that the code is applicable to both internal and external parameter Definitions. The following code sample shows how to find a specific parameter using the definition type.
|
||||
|
||||
**Code Region 8-2: Finding a parameter based on definition type**
|
||||
---
|
||||
|
||||
|
||||
//Find parameter using the Parameter's definition type.
|
||||
public Parameter FindParameter(Element element)
|
||||
{
|
||||
Parameter foundParameter = null;
|
||||
// This will find the first parameter that measures length
|
||||
foreach (Parameter parameter in element.Parameters)
|
||||
{
|
||||
if (parameter.Definition.GetDataType() == SpecTypeId.Length)
|
||||
{
|
||||
foundParameter = parameter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return foundParameter;
|
||||
}
|
||||
|
||||
### Parameter Data Type
|
||||
|
||||
For parameters associated with units of measurement, `GetDataType()` returns a measurable spec identifier. Use `UnitUtils.IsMeasurableSpec(ForgeTypeId)` to detect a measurable spec identifier.
|
||||
|
||||
For Family Type parameters, `GetDataType()` returns a category identifier. Use `Category.IsBuiltInCategory(ForgeTypeId)` to detect a category identifier.
|
||||
|
||||
For all other parameters, `GetDataType()` returns a spec identifier. Use `Parameter.IsSpec(ForgeTypeId)` to detect a spec identifier, including measurable specs.
|
||||
|
||||
### GetGroupTypeId()
|
||||
|
||||
The Definition class GetGroupTypeId() method returns a ForgeTypeId. The members of the GroupTypeId class list all value supported by Revit. The GroupTypeId is used to sort parameters in the Element Properties dialog box.
|
||||
|
||||
## InternalDefinition
|
||||
|
||||
Every Parameter object has an InternalDefinition, which can be obtained from the Definition property. The InternalDefinition represents the parameter definition in the Revit document. In addition to the properties it inherits from Definition, it also has some other key properties.
|
||||
|
||||
### BuiltInParameter
|
||||
|
||||
This property tests whether this definition identifies a built-in parameter or not. For a built-in parameter, this property returns one of the BuiltInParameter enumerated values. For custom-defined parameters, such as shared, global, or family parameters the value will be BuiltInParameter.INVALID.
|
||||
|
||||
### Id
|
||||
|
||||
This property returns the id for the associated ParameterElement if the parameter is not built-in.
|
||||
|
||||
### VariesAcrossGroups
|
||||
|
||||
This property, and the corresponding SetAllowVaryBetweenGroups() method, determine whether the values of this parameter can vary across the related members of group instances. If False, the values will be consistent across the related members in group instances. This can only be set for non-built-in parameters.
|
||||
|
||||
### Visible
|
||||
|
||||
The visible property indicates whether a shared parameter is hidden from the user. This is useful if you wish to add data to an element that is only meaningful to your application and not to the user. This value can only be set when the shared parameter definition is created.
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,95 @@
|
||||
# Formulas and Global Parameters
|
||||
|
||||
# Formulas and Global Parameters
|
||||
|
||||
Formulas may be assigned to non-reporting parameters.
|
||||
|
||||
As with family parameters, formulas may be assigned to global parameters using the GlobalParameter.SetFormula() method. Since a global parameter must be non-reporting to set a formula, a reporting parameter must be changed to non-reporting prior to assigning a formula.
|
||||
|
||||
Value of the evaluated formula must be compatible with the value-type of the parameter. For example, it is permitted to use **Integer** parameters in a formula assigned to a Double (**Number**) parameter, or vice versa. It is not allowed, however, to use **Length** or **Angle** arguments in a formula in a parameter whose type is ether **Integer** or **Number**.
|
||||
|
||||
Formulas may include all standard arithmetic operations and logical operations (as functions **and** , **or** , **not**.) Input to logical operations must be Boolean values (parameters of YesNo type). Consequently, arithmetic operations can be applied to numeric values only. While there are no operations supported for string (text) arguments, strings can be used as results of a logical **If** operation. Depending on their type (and units), parameters of different value types can be combined. However, unit-less values such as **Integer** and **Number** (double) may only be combined with each other.
|
||||
|
||||
Since formulas can get quite complicated, and since some formulas cannot be assigned to certain parameters, the method IsValidFormula() can be used to test whether a formula is valid for a global parameter. If SetFormula() is called with an invalid formula for the global parameter, an Exception will be thrown.
|
||||
|
||||
GetFormula() will return the current formula in the form of a string.
|
||||
|
||||
The following code sample creates four global parameters and then sets a formula to one so that it has a value of either of two other parameters depending on the boolean value of the fourth one.
|
||||
|
||||
**Code Region: Setting a formula**
|
||||
---
|
||||
|
||||
|
||||
public void SetCombinationParameters(Document document)
|
||||
{
|
||||
GlobalParameter gpB = null;
|
||||
GlobalParameter gpT = null;
|
||||
GlobalParameter gpF = null;
|
||||
GlobalParameter gpX = null;
|
||||
|
||||
int TRUE = 1;
|
||||
int FALSE = 0;
|
||||
|
||||
// transaction to create global parameters and set their values
|
||||
using (Transaction trans = new Transaction(document, "Creating global parameters"))
|
||||
{
|
||||
// create 4 new global parameters
|
||||
|
||||
trans.Start();
|
||||
|
||||
gpB = GlobalParameter.Create(document, "GPB", SpecTypeId.Boolean.YesNo);
|
||||
gpT = GlobalParameter.Create(document, "GPT", SpecTypeId.String.Text);
|
||||
gpF = GlobalParameter.Create(document, "GPF", SpecTypeId.String.Text);
|
||||
gpX = GlobalParameter.Create(document, "GPX", SpecTypeId.String.Text);
|
||||
|
||||
// assign initial values and a formula to the global parameters
|
||||
|
||||
gpB.SetValue(new IntegerParameterValue(TRUE));
|
||||
gpT.SetValue(new StringParameterValue("TypeA"));
|
||||
gpF.SetValue(new StringParameterValue("TypeB"));
|
||||
|
||||
// Set the formula to GPX so that its final value is either the value of GPT (TypeA)
|
||||
// or GPF (TypeB) depending on whether the value of GPB is True or False.
|
||||
// Note: in this particular case we are certain the formula is valid, but if weren't
|
||||
// certain, we could use a validation method as we are now going to illustrate here:
|
||||
string expression = "if(GPB,GPT,GPF)"; // XPX <== if (GPB == TRUE) then GPT else GPF
|
||||
if (gpX.IsValidFormula(expression))
|
||||
{
|
||||
gpX.SetFormula(expression);
|
||||
}
|
||||
|
||||
trans.Commit();
|
||||
}
|
||||
|
||||
// we can test that the formula works
|
||||
// since the boolean value is TRUE, the value of the GPX parameter
|
||||
// should be the same as the value of the GPT parameters
|
||||
|
||||
StringParameterValue sTrue = gpT.GetValue() as StringParameterValue;
|
||||
StringParameterValue sFalse = gpF.GetValue() as StringParameterValue;
|
||||
StringParameterValue sValue = gpX.GetValue() as StringParameterValue;
|
||||
|
||||
if (sValue.Value != sTrue.Value)
|
||||
{
|
||||
TaskDialog.Show("Error", "Unexpected value of a global parameter");
|
||||
}
|
||||
|
||||
// we can also test that evaluation of the formula is affected by changes
|
||||
|
||||
using (Transaction trans = new Transaction(document, "Change value of a YesNo parameter"))
|
||||
{
|
||||
trans.Start();
|
||||
gpB.SetValue(new IntegerParameterValue(FALSE));
|
||||
trans.Commit();
|
||||
}
|
||||
|
||||
sValue = gpX.GetValue() as StringParameterValue;
|
||||
|
||||
if (sValue.Value != sFalse.Value)
|
||||
{
|
||||
TaskDialog.Show("Error", "Unexpected value of a global parameter");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
**Parent page:** [Global Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
@@ -0,0 +1,88 @@
|
||||
# GlobalParameter Basics
|
||||
|
||||
# GlobalParameter Basics
|
||||
|
||||
The GlobalParameter class represents a global parameter in a project document and can be used to create and modify global parameters.
|
||||
|
||||
## Creating global parameters
|
||||
|
||||
Global parameters may be created only in project documents, not in families. Global parameters are created via the static Create() method in a given document, with a given name and SpecTypeId. Each new parameter must have a name that is unique within the document, which can be determined using the static GlobalParametersManager.IsUniqueName() method. Global parameters can be created with almost any type of data, but there are a few types that are not currently supported, such as the ElementId type. Test whether a particular data type is appropriate for a global parameter by using the static SpecUtils.IsSpec() method.
|
||||
|
||||
Parameters are created as non-reporting initially, but can be changed after creation using the IsReporting property if the global parameter is of an eligible type. See the [Reporting vs. Non-Reporting Parameters](Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Reporting_vs_Non_Reporting_parameters_html.html "The most significant difference in types of global parameters is whether they are reporting or non-reporting.") page for more information.
|
||||
|
||||
**Code Region: Create a new global parameter**
|
||||
---
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Global Parameter of type Length, assigns it an initial value,
|
||||
/// and uses it to label a set of input dimension elements.
|
||||
/// </summary>
|
||||
/// <param name="document">Revit project document in which to create the parameter.</param>
|
||||
/// <param name="name">Name of the global parameter to create.</param>
|
||||
/// <param name="value">A value the new global parameter is to have.</param>
|
||||
/// <param name="dimensionsToLabel">A set of dimension to labe by the new global parameter.</param>
|
||||
/// <returns>ElementId of the new GlobalParameter</returns>
|
||||
public ElementId CreateNewGlobalParameter(Document document, String name, double value, ISet<ElementId> dimensionsToLabel)
|
||||
{
|
||||
if (!GlobalParametersManager.AreGlobalParametersAllowed(document))
|
||||
throw new System.InvalidOperationException("Global parameters are not permitted in the given document");
|
||||
|
||||
if (!GlobalParametersManager.IsUniqueName(document, name))
|
||||
throw new System.ArgumentException("Global parameter with such name already exists in the document", "name");
|
||||
|
||||
ElementId gpid = ElementId.InvalidElementId;
|
||||
|
||||
// creation of any element must be in a transaction
|
||||
using (Transaction trans = new Transaction(document, "Create Global Parameter"))
|
||||
{
|
||||
trans.Start();
|
||||
|
||||
// create a GP with the given name and type Length
|
||||
GlobalParameter gp = GlobalParameter.Create(document, name, SpecTypeId.Length);
|
||||
if (gp != null)
|
||||
{
|
||||
// if created successfully, assign it a value
|
||||
// note: parameters of type Length accept Double values
|
||||
gp.SetValue(new DoubleParameterValue(value));
|
||||
|
||||
// if a collection of dimensions was given, label them with this new parameter
|
||||
foreach (ElementId elemid in dimensionsToLabel)
|
||||
{
|
||||
// not just any dimension is allowed to be labeled
|
||||
// check first to avoid exceptions
|
||||
if (gp.CanLabelDimension(elemid))
|
||||
{
|
||||
gp.LabelDimension(elemid);
|
||||
}
|
||||
}
|
||||
|
||||
gpid = gp.Id;
|
||||
}
|
||||
trans.Commit();
|
||||
}
|
||||
|
||||
return gpid;
|
||||
}
|
||||
|
||||
## Getting and setting the value of a global parameter
|
||||
|
||||
All global parameters, formula-driven, dimension-driven, or independent, have values. A value can be obtained by calling the GetValue() method. The object returned by that method is an instance of one of the classes derived from the ParameterValue class:
|
||||
|
||||
* IntegerParameterValue
|
||||
* DoubleParameterValue
|
||||
* StringParameterValue
|
||||
|
||||
|
||||
|
||||
All the derived classes have only one property, Value, which gets or sets the value as the corresponding type.
|
||||
|
||||
The concrete instance is determined by the type of the global parameter which was specified upon creation. Parameters that are neither formula-driven nor dimension-driven (reporting) can have a value assigned. The method to use is SetValue() and it accepts the same type of ParameterValue that is returned by GetValue(). However, the type can also be deduced easily: **Text** parameters accept only StringParameterValue. **Integer** and **YesNo** parameters accept only IntegerParameterValue. All other parameters accept only DoubleParameterValue.
|
||||
|
||||
## Elements affected by a global parameter
|
||||
|
||||
Global parameters can be associated with other global parameters as well as regular family instance parameters (which may report global parameters as their values via the assignment formula). There are two methods available to find relations among parameters: GlobalParameter.GetAffectedGlobalParameters() and GlobalParameter.GetAffectedElements(). The former returns all other global parameters that refer to a particular global parameter in their respective formulas. The latter method returns a set of all elements of which some parameters are controlled by the global parameter. These two methods together with the GlobalParameter.GetLabeledDimensions() can help determine out how model elements relate to each other via global parameters.
|
||||
|
||||
Methods for maintaining associations between element properties and global parameters can be found in the [Parameter](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Parameter_html.html "The Parameter class contains the value for the given parameter.") class.
|
||||
|
||||
**Parent page:** [Global Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
@@ -0,0 +1,134 @@
|
||||
# Labeling Dimensions with Global Parameters
|
||||
|
||||
# Labeling Dimensions with Global Parameters
|
||||
|
||||
A key feature of global parameters is their ability to "label" dimensions.
|
||||
|
||||
When a dimension is labeled by a global parameter, then its value is either controlled by the parameter (non-reporting), or drives the value of the parameter (reporting). It is important to note that a reporting parameter can label at most one dimension object - meaning, a parameter can be driven by one dimension only. If the dimension has several segments and is labeled by a non-reporting parameter, the value of each segment will be driven by this parameter. Multi-segmented dimensions cannot be labeled by reporting parameters.
|
||||
|
||||
If the dimension is already labeled by another global parameter, labeling it again will automatically detach it from that parameter.
|
||||
|
||||
Presently, only single **Linear** and **Angular** dimensions can be labeled, but there are other restrictions in effect too. Use the CanLabelDimension() method to find out whether a particular dimension element may be labeled or not. Also, since the value of the parameter and the dimension labeled by it depend on each other, the data type of the global parameter must be either **Length** or **Angle** , since those are the only units a dimension can represent.
|
||||
|
||||
The following example creates a global parameter and uses it to label the set of given dimension elements.
|
||||
|
||||
**Code Region: Labeling dimensions**
|
||||
---
|
||||
|
||||
|
||||
public int DriveSelectedDimensions(Document document, string name, double value, ISet<ElementId> dimset)
|
||||
{
|
||||
if (!GlobalParametersManager.AreGlobalParametersAllowed(document))
|
||||
throw new System.InvalidOperationException("Global parameters are not permitted in the given document");
|
||||
|
||||
if (!GlobalParametersManager.IsUniqueName(document, name))
|
||||
throw new System.ArgumentException("Global parameter with such name already exists in the document", "name");
|
||||
|
||||
if (value <= 0.0)
|
||||
throw new System.ArgumentException("Value of a global parameter that drives dimension must be a positive number", "value");
|
||||
|
||||
int nLabeledDims = 0; // number of labeled dimensions (for testing)
|
||||
|
||||
// creation of any element must be in a transaction
|
||||
using (Transaction trans = new Transaction(document, "Create Global Parameter"))
|
||||
{
|
||||
trans.Start();
|
||||
|
||||
// create a GP with the given name and type Length
|
||||
// Note: Length (or Angle) is required type of global parameters that are to label a dimension
|
||||
GlobalParameter newgp = GlobalParameter.Create(document, name, SpecTypeId.Length);
|
||||
if (newgp != null)
|
||||
{
|
||||
newgp.SetValue(new DoubleParameterValue(value));
|
||||
|
||||
// use the parameter to label the given dimensions
|
||||
foreach (ElementId elemid in dimset)
|
||||
{
|
||||
// not just any dimension is allowed to be labeled
|
||||
// check first to avoid exceptions
|
||||
if (newgp.CanLabelDimension(elemid))
|
||||
{
|
||||
newgp.LabelDimension(elemid);
|
||||
nLabeledDims += 1;
|
||||
}
|
||||
}
|
||||
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
// for illustration purposes only, we'll test the results of our modifications
|
||||
|
||||
// 1.) Check the new parameter can be found
|
||||
|
||||
ElementId gpid = GlobalParametersManager.FindByName(document,name);
|
||||
if (gpid == ElementId.InvalidElementId)
|
||||
{
|
||||
TaskDialog.Show("Error", "Failed to find a newly created global parameter");
|
||||
}
|
||||
|
||||
GlobalParameter gp = document.GetElement(gpid) as GlobalParameter;
|
||||
|
||||
// 2\. Check the number of labeled dimension is as expected
|
||||
|
||||
ISet<ElementId> labeledSet = gp.GetLabeledDimensions();
|
||||
if (labeledSet.Count != nLabeledDims)
|
||||
{
|
||||
TaskDialog.Show("Error", "Have not found all the dimension that were labeled.");
|
||||
}
|
||||
|
||||
return labeledSet.Count;
|
||||
}
|
||||
|
||||
The SetDrivingDimension() method combines two actions: a) Making the parameter reporting if it is not yet, and b) Labeling the given dimension with it. Therefore, the global parameter must be eligible for reporting, and must not be used to label more than one dimensions yet. See the [Reporting vs. Non-Reporting Parameters](Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Reporting_vs_Non_Reporting_parameters_html.html "The most significant difference in types of global parameters is whether they are reporting or non-reporting.") page for more information on reporting parameters.
|
||||
|
||||
In case this parameter is already driven by another dimension, the other dimension will be unlabeled first before the given one is labeled. This is because a reporting parameter can only label one dimension at a time (i.e., it can be driven by one dimension only).
|
||||
|
||||
The next example creates a global parameter to be driven by the value of a dimension.
|
||||
|
||||
**Code Region: Assign driving dimension**
|
||||
---
|
||||
|
||||
|
||||
public bool AssignDrivingDimension(Document document, ElementId gpid, ElementId dimid)
|
||||
{
|
||||
// we expect to find the global parameter in the document
|
||||
GlobalParameter gp = document.GetElement(gpid) as GlobalParameter;
|
||||
if (gp == null)
|
||||
return false;
|
||||
|
||||
// we expect to find the given dimension in the document
|
||||
Dimension dim = document.GetElement(dimid) as Dimension;
|
||||
if (dim == null)
|
||||
return false;
|
||||
|
||||
// not every global parameter can label
|
||||
// and not every dimension can be labeled
|
||||
if (!gp.CanLabelDimension(dimid))
|
||||
return false;
|
||||
|
||||
// we need a transaction to modify the model
|
||||
using (Transaction trans = new Transaction(document,"Assign a driving dimension"))
|
||||
{
|
||||
trans.Start();
|
||||
|
||||
// we cannot assign a driving dimension to a global
|
||||
// parameter that is already used to label other dimensions
|
||||
ISet<ElementId> dimset = gp.GetLabeledDimensions();
|
||||
foreach (ElementId elemid in dimset)
|
||||
{
|
||||
gp.UnlabelDimension(elemid);
|
||||
}
|
||||
|
||||
// with the GP free of all previously labels (if there were any)
|
||||
gp.SetDrivingDimension(dimid);
|
||||
|
||||
// we should be able to commit, but we test the result anyway
|
||||
if (trans.Commit() != TransactionStatus.Committed)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
**Parent page:** [Global Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
@@ -0,0 +1,57 @@
|
||||
# Managing Global Parameters
|
||||
|
||||
# Managing Global Parameters
|
||||
|
||||
The GlobalParametersManager class provides access to general information and data of Global Parameter elements in a particular model.
|
||||
|
||||
GlobalParametersManager provides the main access point to managing global parameters in a project document. It provides static methods to access and reorder global parameters and to test for name uniqueness and Id validity.
|
||||
|
||||
## Accessing global parameters
|
||||
|
||||
Global parameters are only supported in project documents, not family documents. Even with a project document, however, global parameters may be disallowed under certain circumstances, either temporarily or permanently. The AreGlobalParametersAllowed() method will indicate whether global parameters are allowed within a specified document.
|
||||
|
||||
If global parameters are allowed in a project document, use the methods GetAllGlobalParameters() to get all global parameters in a specified document, or GetGlobalParametersOrdered() to get an ordered list of the global parameters. When retrieving an ordered list, the order of the items corresponds to the order in which global parameters appear in the standard Global Parameters dialog in the Revit user interface.
|
||||
|
||||
To get a global parameter by name, call FindByName(), which will return the ElementId of the named global parameter, or ElementId.InvalidElementId if no global parameter is found with the given name. Since global parameter names must be unique, the IsUniqueName() method should be called to check a name prior to creating a new GlobalParameter.
|
||||
|
||||
Given an ElementId for a GlobalParameter, the IsValidGlobalParameter() will confirm that the given ElementId is a valid global parameter id.
|
||||
|
||||
The following example demonstrates how to get all global parameters, if global parameters are allowed in the document.
|
||||
|
||||
**Code Region: Getting global parameters**
|
||||
---
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns all global parameter elements defined in the given document.
|
||||
/// </summary>
|
||||
/// <param name="document">Revit project document.</param>
|
||||
/// <returns>A set of ElementIds of global parameter elements</returns>
|
||||
public ISet<ElementId> GetAllGlobalParameters(Document document)
|
||||
{
|
||||
// Global parameters are not available in all documents.
|
||||
// They are available in projects, but not in families.
|
||||
if (GlobalParametersManager.AreGlobalParametersAllowed(document))
|
||||
{
|
||||
return GlobalParametersManager.GetAllGlobalParameters(document);
|
||||
}
|
||||
|
||||
// return an empty set if global parameters are not available in the document
|
||||
return new HashSet<ElementId>();
|
||||
}
|
||||
|
||||
## Reordering global parameters
|
||||
|
||||
GlobalParametersManager provides methods to change the given order of the global parameters in the project document. These operations have no effect on the global parameters themselves. The rearranged order is only visible in the standard Global Parameters dialog in Revit and reflected in the GetGlobalParametersOrdered() method.
|
||||
|
||||
* SortParameters() - sorts the global parameters in either ascending or descending alphabetical order, but only within the range of their respective parameter group.
|
||||
* MoveParameterDownOrder() - moves a given parameter down in the current order.
|
||||
* MoveParameterUpOrder() - moves the given parameter up in the current order.
|
||||
|
||||
|
||||
|
||||
A parameter can only be moved within its parameter group, so if a parameter can no longer move because it is at the boundary of its group, the MoveParameter methods will return False.
|
||||
|
||||
The method ParameterUtils.GetBuiltInParameterGroupTypeId() gets the parameter group identifier corresponding to the given built-in parameter identifier.
|
||||
|
||||
**Parent page:** [Global Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
@@ -0,0 +1,25 @@
|
||||
# Reporting vs. Non-Reporting Parameters
|
||||
|
||||
# Reporting vs. Non-Reporting Parameters
|
||||
|
||||
The most significant difference in types of global parameters is whether they are reporting or non-reporting.
|
||||
|
||||
## What are reporting and non-reporting parameters?
|
||||
|
||||
There are several ways global parameters can be categorized, but probably the most significant categorization stems from the GlobalParameter.IsReporting property which divides global parameters into two groups - Reporting and Non-Reporting. The significance of reporting parameters lays in the fact that their values are driven by the dimension that has been labeled by a reporting parameter. It means that the value of a reporting parameter reflects the value of a dimension (length or angle) and gets updated anytime the dimension changes. Non-Reporting parameters behave in the opposite manner - they drive value of dimensions that have been labeled by them, which results in controlling the model's geometry through global parameters' values.
|
||||
|
||||
Reporting parameters are limited in several ways. They can be only of **Length** or **Angle** type, a requirement due to the fact that a dimension must be able to drive the value. For the same reason reporting parameters may not have formulas.
|
||||
|
||||
Non-Reporting parameters, on the other way, can be of almost any type (**Length** , **Integer** , **Area** , etc.) with the exception of ElementId type. Also, Non-Reporting parameters may have assigned formulas in which other global parameters may be used as arguments. This way one global parameter's value can be derived from other parameter (or parameters), and the other parameter can be either reporting or non-reporting.
|
||||
|
||||
Other important properties of global parameters are IsDrivenByDimension and IsDrivenByFormula, which are mutually exclusive - a parameter that has a formula assigned cannot be driven by a dimension (nor can be reporting) and vice versa.
|
||||
|
||||
## Making a global parameter reporting or non-reporting
|
||||
|
||||
Global parameters are initially non-reporting upon creation, but can be set to reporting use the GlobalParameter.IsReporting property once a global parameter is created and is of an eligible type. Use GlobalParameter.HasValidTypeForReporting() to ensure that a certain data type can be made reporting. Note, that a parameter may not be made reporting after more than one dimension has been labeled by it. It is because reporting parameters can label (and be driven) by one dimension only.
|
||||
|
||||
An alternative way of making a parameter reporting is via the GlobalParameter.SetDrivingDimension() method which labels one dimension by a global parameter and also makes the parameter reporting if it is not reporting yet.
|
||||
|
||||
Although parameters driven by a dimension are automatically made reporting, parameters driven by a formula are not. In order to set a formula, the global parameter must be non-reporting. Therefore a reporting parameter must be changed to non-reporting first before assigning a formula.
|
||||
|
||||
**Parent page:** [Global Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
@@ -0,0 +1,19 @@
|
||||
# Global Parameters
|
||||
|
||||
# Global Parameters
|
||||
|
||||
Global parameters support controlling geometry constraints through special parameters defined in a project document.
|
||||
|
||||
Global Parameters can be used for both labeling and reporting to/from dimensions, as well as setting values of instance parameters. They can be used to drive values of dimensions or other elements' parameters and they can be driven by a selected dimension, the value of which then determines the value of the global parameter.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Managing Global Parameters](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Managing_Global_Parameters_html.html)
|
||||
* [GlobalParameter Basics](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_GlobalParameter_Basics_html.html)
|
||||
* [Reporting vs. Non-Reporting Parameters](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Reporting_vs_Non_Reporting_parameters_html.html)
|
||||
* [Formulas and Global Parameters](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Formulas_and_Global_Parameters_html.html)
|
||||
* [Labeling Dimensions with Global Parameters](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_Labeling_Dimensions_with_Global_Parameters_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,45 @@
|
||||
# Parameter Relationships
|
||||
|
||||
# Parameter Relationships
|
||||
|
||||
Parameters can be affected by each other.
|
||||
|
||||
There are relationships between Parameters where the value of one Parameter can affect:
|
||||
|
||||
* whether another Parameter can be set, or is read-only
|
||||
* what parameters are valid for the element
|
||||
* the computed value of another parameter
|
||||
|
||||
|
||||
|
||||
Additionally, some parameters are always read-only.
|
||||
|
||||
Some parameters are computed in Revit, such as wall Length and Area parameter. These parameters are always read-only because they depend on the element's internal state.
|
||||
|
||||
**Figure 29: Wall computed parameters**
|
||||
|
||||
In this code sample, the Sill Height parameter for an opening is adjusted, which results in the Head Height parameter being re-computed:
|
||||
|
||||
**Code Region: Parameter relationship example**
|
||||
---
|
||||
|
||||
|
||||
// opening should be an opening such as a window or a door
|
||||
public void ShowParameterRelationship(FamilyInstance opening)
|
||||
{
|
||||
// get the original Sill Height and Head Height parameters for the opening
|
||||
Parameter sillPara = opening.GetParameter(ParameterTypeId.InstanceSillHeightParam);
|
||||
Parameter headPara = opening.GetParameter(ParameterTypeId.InstanceHeadHeightParam);
|
||||
double sillHeight = sillPara.AsDouble();
|
||||
double origHeadHeight = headPara.AsDouble();
|
||||
|
||||
// Change the Sill Height only and notice that Head Height is recalculated
|
||||
sillPara.Set(sillHeight + 2.0);
|
||||
double newHeadHeight = headPara.AsDouble();
|
||||
TaskDialog.Show("Info", "Old head height: " + origHeadHeight + "; new head height: "
|
||||
+ newHeadHeight);
|
||||
}
|
||||
|
||||
Global parameters also have relationships with other parameters. See the [GlobalParameter Basics](Global_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_GlobalParameter_Basics_html.html "The GlobalParameter class represents a global parameter in a project document and can be used to create and modify global parameters.") topic for more information.
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,103 @@
|
||||
# Parameter
|
||||
|
||||
# Parameter
|
||||
|
||||
The Parameter class contains the value for the given parameter.
|
||||
|
||||
All Elements within Autodesk Revit contain Parameters, which can be retrieved as a set or individually. An individual parameter object can be obtained from any Element using either a BuiltInParameter enumeration, a Definition object or a Shared Parameter GUID.
|
||||
|
||||
The data contained within the parameter can be either a Double, Integer, String or ElementId, as indicated by its StorageType property. For value types, the DisplayUnitType property will indicate the display unit used for the parameter value. The Parameter object also contains a [Definition](Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Definition_html.html "The Definition object describes the data type, name, and other Parameter details.") object that describes the data type, name and other details of the parameter.
|
||||
|
||||
## StorageType
|
||||
|
||||
StorageType describes the type of parameter values stored internally.
|
||||
|
||||
Based on the property value, use the corresponding get and set methods to retrieve and set the parameter data value.
|
||||
|
||||
The StorageType is an enumerated type that lists all internal parameter data storage types supported by Revit:
|
||||
|
||||
**Member Name** | **Description**
|
||||
---|---
|
||||
_String_ | Internal data is stored as a string of characters.
|
||||
_ElementId_ | Data type represents an element and is stored as an Element ID.
|
||||
_Double_ | Data is stored internally as an 8-byte floating point number.
|
||||
_Integer_ | Internal data is stored as a signed 32-bit integer.
|
||||
_None_ | None represents an invalid storage type. For internal use only.
|
||||
In most cases, the ElementId value is a positive number. However, it can be a negative number. When the ElementId value is negative, it does not represent an Element but has another meaning. For example, the storage type parameter for a beam's Vertical Projection is ElementId. When the parameter value is Level 1 or Level 2, the ElementId value is positive and corresponds to the ElementId of that level. However, when the parameter value is set to Auto-detect, Center of Beam or Top of Beam, the ElementId value is negative.
|
||||
|
||||
The following code sample shows how to check whether a parameter's value can be set to a double value, based on its StorageType:
|
||||
|
||||
**Code Region: Checking a parameter's StorageType**
|
||||
---
|
||||
|
||||
|
||||
public bool SetParameter(Parameter parameter, double value)
|
||||
{
|
||||
bool result = false;
|
||||
//if the parameter is readonly, you can't change the value of it
|
||||
if (null != parameter && !parameter.IsReadOnly)
|
||||
{
|
||||
StorageType storageType = parameter.StorageType;
|
||||
if (StorageType.Double != storageType)
|
||||
{
|
||||
throw new Exception("The storagetypes of value and parameter are different!");
|
||||
}
|
||||
|
||||
//If successful, the result is true
|
||||
result = parameter.Set(value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
The Set() method return value indicates that the Parameter value was changed. The Set() method returns true if the Parameter value was changed, otherwise it returns false.
|
||||
|
||||
Not all Parameters are writable. An Exception is thrown if the Parameter is read-only.
|
||||
|
||||
## AsValueString() and SetValueString()
|
||||
|
||||
These two Parameter class methods only apply to value type parameters, which are double or integer parameters representing a measured quantity.
|
||||
|
||||
Use the AsValueString() method to get the parameter value as a string with the unit of measure. For example, the Base Offset value, a wall parameter, is a Double value. Usually the value is shown as a string like -20'0" in the Element Properties. Using the AsValueString() method, you get the -20'0" string value directly. Using the AsDouble() method, you get a double value like -20 without the units of measure.
|
||||
|
||||
Use the SetValueString() method to change the value of a value type parameter instead of using the Set() method. The following code sample illustrates how to change the parameter value using the SetValueString() method:
|
||||
|
||||
**Code Region: Using Parameter.SetValueString()**
|
||||
---
|
||||
|
||||
|
||||
public bool SetWithValueString(Parameter foundParameter)
|
||||
{
|
||||
bool result = false;
|
||||
if (!foundParameter.IsReadOnly)
|
||||
{
|
||||
//If successful, the result is true
|
||||
result = foundParameter.SetValueString("-22\'3\"");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
## Global parameter associations
|
||||
|
||||
The Parameter class has several methods for maintaining associations between element parameters and global parameters. The method GetAssociatedGlobalParameter() returns the ElementId of a global parameter, if any, currently associated with a parameter. InvalidElementId is returned in case this parameter is not associated with any global parameter. InvalidElementId is also returned if called for a parameter that cannot even be associated with a global parameters (i.e. a non-parameterizable parameter or a parameter with a formula).
|
||||
|
||||
There are two methods to determine if a parameter can be associated with global parameters. Parameter.CanBeAssociatedWithGlobalParameters() tests wether a parameter can be associated with any global parameter. Only properties defined as parametrizable can be associated with global parameters. That excludes any read-only and formula-driven parameters, as well as those that have other explicit or implicit restrictions imposed by Revit. To test whether a specific global parameter can be associated with this parameter, use Parameter.CanBeAssociatedWithGlobalParameter(). Keep in mind that the parameter's value type must match the type of the global parameter to create an association.
|
||||
|
||||
For parameters that can be associated with a global parameter, use AssociateWithGlobalParameter() to create the association. Once associated, the parameter can be later dissociated by calling the DissociateFromGlobalParameter() method.
|
||||
|
||||
## ParameterUtils
|
||||
|
||||
ParameterUtils is a class with static utility functions related to ForgeTypeId parameter identifiers:
|
||||
|
||||
* ParameterUtils.GetAllBuiltInGroups()
|
||||
* ParameterUtils.GetAllBuiltInParameters()
|
||||
* ParameterUtils.IsBuiltInGroup(ForgeTypeId)
|
||||
* ParameterUtils.IsBuiltInParameter(ForgeTypeId)
|
||||
|
||||
|
||||
|
||||
## Multiple Values
|
||||
|
||||
The `MultipleValuesIndicationSettings` class allows access to the custom value used in instances of the Properties dialog, Tags, and Schedules when multiple elements are referenced and the value of the parameter is differs among those elements.
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,123 @@
|
||||
# Binding
|
||||
|
||||
# Binding
|
||||
|
||||
Binding is what ties shared parameters to elements in certain categories in the model.
|
||||
|
||||
There are two types of binding available: Instance binding and Type binding. The key difference between the two is that the instance bound parameters appear on all instances of the elements in those categories. Changing the parameter on one does not affect the other instances of the parameter. The Type bound parameters appear only on the type object and is shared by all the instances that use that type. Changing the type bound parameter affects all instances of the elements that use that type. Note, a definition can only be bound to an instance or a type and not both.
|
||||
|
||||
To bind a parameter:
|
||||
|
||||
1. Use an InstanceBinding or a TypeBinding object to create a new Binding object that includes the categories to which the parameter is bound.
|
||||
2. Add the binding and definition to the document using the BindingMap object available from the Document.ParameterBindings property.
|
||||
|
||||
|
||||
|
||||
The following class and method in the Autodesk.Revit.DB namespace provide more information on binding parameters to elements.
|
||||
|
||||
* BindingMap Class
|
||||
* Retrieved from the Document.ParameterBindings property.
|
||||
* Parameter binding connects a parameter definition to elements within one or more categories.
|
||||
* The map is used to interrogate existing bindings as well as generate new parameter bindings using the Insert method.
|
||||
* BindingMap.Insert() Method
|
||||
* The binding object type dictates whether the parameter is bound to all instances or just types.
|
||||
* A parameter definition cannot be bound to both instances and types.
|
||||
* If the parameter binding exists, the method returns false.
|
||||
|
||||
|
||||
|
||||
### Type Binding
|
||||
|
||||
The TypeBinding objects are used to bind a property to a Revit type, such as a wall type. It differs from Instance bindings in that the property is shared by all instances identified in type binding. Changing the parameter for one type affects all instances of the same type.
|
||||
|
||||
The following code sample demonstrates how to add parameter definitions using a shared parameter file. The following code performs the same actions as using the dialog box in the Revit UI. Parameter definitions are created in the following order:
|
||||
|
||||
1. A shared parameter file is created.
|
||||
2. A definition group and a parameter definition are created for the Walls type.
|
||||
3. The definition is bound to the wall type parameter in the current document based on the wall category.
|
||||
|
||||
|
||||
|
||||
#### Code Region 22-7: Adding type parameter definitions using a shared parameter file
|
||||
|
||||
|
||||
public bool SetNewParameterToTypeWall(UIApplication app, DefinitionFile myDefinitionFile)
|
||||
{
|
||||
// Create a new group in the shared parameters file
|
||||
DefinitionGroups myGroups = myDefinitionFile.Groups;
|
||||
DefinitionGroup myGroup = myGroups.Create("MyParameters");
|
||||
|
||||
// Create a type definition
|
||||
ExternalDefinitionCreationOptions option = new ExternalDefinitionCreationOptions("CompanyName", SpecTypeId.String.Text);
|
||||
Definition myDefinition_CompanyName = myGroup.Definitions.Create(option);
|
||||
|
||||
// Create a category set and insert category of wall to it
|
||||
CategorySet myCategories = app.Application.Create.NewCategorySet();
|
||||
// Use BuiltInCategory to get category of wall
|
||||
Category myCategory = Category.GetCategory(app.ActiveUIDocument.Document, BuiltInCategory.OST_Walls);
|
||||
|
||||
myCategories.Insert(myCategory);
|
||||
|
||||
//Create an object of TypeBinding according to the Categories
|
||||
TypeBinding typeBinding = app.Application.Create.NewTypeBinding(myCategories);
|
||||
|
||||
// Get the BingdingMap of current document.
|
||||
BindingMap bindingMap = app.ActiveUIDocument.Document.ParameterBindings;
|
||||
|
||||
// Bind the definitions to the document
|
||||
bool typeBindOK = bindingMap.Insert(myDefinition_CompanyName, typeBinding,
|
||||
BuiltInParameterGroup.PG_TEXT);
|
||||
return typeBindOK;
|
||||
}
|
||||
|
||||
### Instance Binding
|
||||
|
||||
The InstanceBinding object indicates binding between a parameter definition and a parameter in certain category instances.
|
||||
|
||||
Once bound, the parameter appears in all property dialog boxes for the instance (if the visible property is set to true). Changing the parameter in any one instance does not change the value in any other instance.
|
||||
|
||||
The following code sample demonstrates how to add parameter definitions using a shared parameter file. Parameter definitions are added in the following order:
|
||||
|
||||
1. A shared parameter file is created.
|
||||
2. A definition group and a definition for all Walls instances is created.
|
||||
3. Definitions are bound to each wall instance parameter in the current document based on the wall category.
|
||||
|
||||
|
||||
|
||||
#### Code Region 22-8: Adding instance parameter definitions using a shared parameter file
|
||||
|
||||
|
||||
public bool SetNewParameterToInstanceWall(UIApplication app, DefinitionFile myDefinitionFile)
|
||||
{
|
||||
// create a new group in the shared parameters file
|
||||
DefinitionGroups myGroups = myDefinitionFile.Groups;
|
||||
DefinitionGroup myGroup = myGroups.Create("MyParameters1");
|
||||
|
||||
// create an instance definition in definition group MyParameters
|
||||
ExternalDefinitionCreationOptions option = new ExternalDefinitionCreationOptions("Instance_ProductDate", SpecTypeId.String.Text);
|
||||
// Don't let the user modify the value, only the API
|
||||
option.UserModifiable = false;
|
||||
// Set tooltip
|
||||
option.Description = "Wall product date";
|
||||
Definition myDefinition_ProductDate = myGroup.Definitions.Create(option);
|
||||
|
||||
// create a category set and insert category of wall to it
|
||||
CategorySet myCategories = app.Application.Create.NewCategorySet();
|
||||
// use BuiltInCategory to get category of wall
|
||||
Category myCategory = Category.GetCategory(app.ActiveUIDocument.Document, BuiltInCategory.OST_Walls);
|
||||
|
||||
myCategories.Insert(myCategory);
|
||||
|
||||
//Create an instance of InstanceBinding
|
||||
InstanceBinding instanceBinding = app.Application.Create.NewInstanceBinding(myCategories);
|
||||
|
||||
// Get the BingdingMap of current document.
|
||||
BindingMap bindingMap = app.ActiveUIDocument.Document.ParameterBindings;
|
||||
|
||||
// Bind the definitions to the document
|
||||
bool instanceBindOK = bindingMap.Insert(myDefinition_ProductDate,
|
||||
instanceBinding, BuiltInParameterGroup.PG_TEXT);
|
||||
return instanceBindOK;
|
||||
}
|
||||
|
||||
**Parent page:** [Shared Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_html.html)
|
||||
@@ -0,0 +1,67 @@
|
||||
# Definition File
|
||||
|
||||
# Definition File
|
||||
|
||||
The DefinitionFile object represents a shared parameter file which is a common text file.
|
||||
|
||||
# Format
|
||||
|
||||
The shared parameter definition file is a text file (.txt) with three blocks: META, GROUP and PARAM. The GROUP and PARAM blocks are relevant to the shared parameter functionality in the Revit API. Do not edit the definition file directly; instead, edit it using the UI or the API.
|
||||
|
||||
Although the Revit API takes care of reading and writing this file, the following section provides information the format of the file, which closely corresponds to the API objects and methods used to access shared parameters. The file uses tabs to separate fields and can be difficult to read in a text editor. The code region below shows the contents of a sample shared parameter text file.
|
||||
|
||||
**Code Region 22-1: Parameter definition file example**
|
||||
---
|
||||
|
||||
|
||||
# This is a Revit shared parameter file.
|
||||
# Do not edit manually.
|
||||
*META VERSION MINVERSION
|
||||
META 2 1
|
||||
*GROUP ID NAME
|
||||
GROUP 1 MyGroup
|
||||
GROUP 2 AnotherGroup
|
||||
*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE DESCRIPTION USERMODIFIABLE
|
||||
PARAM bb7f0005-9692-4b76-8fa3-30cec8aecf74 Price INTEGER 2 1 Enter price in USD 1
|
||||
PARAM b7ea2654-b206-4694-a087-756359b52e7f areaTags FAMILYTYPE -2005020 1 1 1
|
||||
PARAM d1a5439d-dc8d-4053-99fa-2f33804bae0e MyParam TEXT 1 1 1
|
||||
|
||||
* The GROUP block contains group entries that associate every parameter definition with a group. The following fields appear in the GROUP block:
|
||||
|
||||
* ID - Uniquely identifies the group and associates the parameter definition with a group.
|
||||
* Name - The group name displayed in the UI.
|
||||
* The PARAM block contains parameter definitions. The following fields appear in the PARAM block:
|
||||
|
||||
* GUID - Identifies the parameter definition.
|
||||
|
||||
* NAME - Parameter definition name.
|
||||
|
||||
* DATATYPE - Parameter type. This field can be a common type (TEXT, INTEGER, etc.), structural type (FORCE, MOMENT, etc.) or common family type (Area Tags, etc). Common type and structural type parameters are specified in the text file directly (e.g., TEXT, FORCE). If the value of the DATATYPE field is FAMILYTYPE, an extra number is added. For example, FAMILYTYPE followed by -2005020 represents Family type: Area Tags.
|
||||
|
||||
* DATACATEGORY - An optional field for parameters whose DATATYPE is FAMILYTYPE.
|
||||
|
||||
* GROUP - A group ID used to identify the group that includes the current parameter definition.
|
||||
|
||||
* VISIBLE - Identifies whether the parameter is visible. The value of this field is 0 or 1.0 = invisible
|
||||
|
||||
1 = visible
|
||||
|
||||
* DESCRIPTION - An optional field for a tooltip for this parameter.
|
||||
|
||||
* USERMODIFIABLE - Identifies whether the parameter is editable by the user.0 = user cannot edit the parameter and it is greyed out in the UI
|
||||
|
||||
1 = user can edit the parameter value in the UI
|
||||
|
||||
|
||||
|
||||
|
||||
In the sample definition file, there are two groups:
|
||||
|
||||
* MyGroup - ID 1 - Contains the parameter definition for MyParam which is a Text type parameter, and the definition for areaTags which is a FamilyType parameter.
|
||||
* AnotherGroup - ID 2 - Contains the parameter definition for Price which is an Integer type parameter.
|
||||
|
||||
|
||||
|
||||
Of the 3 parameters in the sample file, only Price has a description. All of the parameters are visible and user modifiable.
|
||||
|
||||
**Parent page:** [Shared Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_html.html)
|
||||
@@ -0,0 +1,71 @@
|
||||
# SharedParameterElement
|
||||
|
||||
# SharedParameterElement
|
||||
|
||||
SharedParameterElements store information about a particular user-defined shared parameter in the document.
|
||||
|
||||
User-defined parameters are stored in the document and represented by the ParameterElement class. The subclass SharedParameterElement represents a shared parameter loaded into the document. ParemeterElement is also the base class for GlobalParameter.
|
||||
|
||||
Once a shared parameter has been loaded into a document, information about it can be retrieved from the SharedParameterElement class. SharedParameterElement inherits the GetDefinition() method from the parent ParameterElement class. GetDefinition() returns the InternalDefinition that represents the definition for the parameter in the document, as opposed to the ExternalDefinition for a shared parameter that is stored in the shared parameter file. SharedParameterElement also provides access to the Guid that identifies the shared parameter via the GuidValue property.
|
||||
|
||||
The static Create() method on this class can create a new SharedParameterElement in the document from an ExternalDefinition.
|
||||
|
||||
The static Lookup() method can retrieve a SharedParameterElement from a given GUID.
|
||||
|
||||
In the following example, a schedule contains a field representing the value of a shared parameter. The definition for the shared parameter is retrieved from the SharedParameterElement.
|
||||
|
||||
**Code Region: Getting the definition of a shared parameter**
|
||||
---
|
||||
|
||||
|
||||
// Check if a given shared parameter in a schedule can vary across groups
|
||||
public bool CanParamVaryAcrossGroups(ViewSchedule schedule, string sharedParamName)
|
||||
{
|
||||
bool variesAcrossGroups = false;
|
||||
|
||||
int numFields = schedule.Definition.GetFieldCount();
|
||||
// Find the field with the given name
|
||||
for (int i = 0; i < numFields; i++)
|
||||
{
|
||||
ScheduleField field = schedule.Definition.GetField(i);
|
||||
if (field.GetName().Contains(sharedParamName))
|
||||
{
|
||||
// Get the SharedParameterElement from the field's parameter id
|
||||
SharedParameterElement spe = schedule.Document.GetElement(field.ParameterId) as SharedParameterElement;
|
||||
if (spe != null)
|
||||
{
|
||||
InternalDefinition definition = spe.GetDefinition();
|
||||
variesAcrossGroups = definition.VariesAcrossGroups;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variesAcrossGroups;
|
||||
}
|
||||
|
||||
SharedParameterElements are especially useful when working with [Rebar Containers](../../../Discipline_Specific_Functionality/Structural_Engineering/Structural_Model_Elements/Reinforcement/Rebar_Containers.html "Rebar Containers are elements which represent an aggregation of rebars in one host. This element can only be created via the API."). A shared parameter can be added as an override to the parameters manager for a RebarContainer. The shared parameter does not need to be bound to any categories to be added as an override. The following example adds a given shared parameter as an override to a RebarContainer.
|
||||
|
||||
**Code Region: Using a SharedParameterElement as an override for a RebarContainer**
|
||||
---
|
||||
|
||||
|
||||
// Find the named shared parameter and add it as an override to the parameter manger for the given RebarContainer
|
||||
void AddSharedParameterOverride(RebarContainer container, string sharedParamName)
|
||||
{
|
||||
// find the shared parameter guid
|
||||
FilteredElementCollector collector = new FilteredElementCollector(container.Document);
|
||||
collector.OfClass(typeof(SharedParameterElement));
|
||||
IEnumerable<SharedParameterElement> paramCollector = collector.Cast<SharedParameterElement>();
|
||||
|
||||
foreach (SharedParameterElement spe in paramCollector)
|
||||
{
|
||||
if (spe.Name.CompareTo(sharedParamName) == 0)
|
||||
{
|
||||
RebarContainerParameterManager paramManager = container.GetParametersManager();
|
||||
paramManager.AddSharedParameterAsOverride(spe.Id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Shared Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_html.html)
|
||||
@@ -0,0 +1,137 @@
|
||||
# Working with the Definition File
|
||||
|
||||
# Working with the Definition File
|
||||
|
||||
The definition file provides access to shared parameters.
|
||||
|
||||
## Accessing parameters in the definition file
|
||||
|
||||
Use the following steps to gain access to the definition file and its parameters:
|
||||
|
||||
1. Specify the Application.SharedParametersFilename property with an existing text file or a new one.
|
||||
2. Open the shared parameters file, using the Application.OpenSharedParameterFile() method.
|
||||
3. Open an existing group or create a new group using the DefinitionFile.Groups property.
|
||||
4. Open an existing external parameter definition or create a new definition using the DefinitionGroup.Definitions property.
|
||||
|
||||
|
||||
|
||||
The following classes and methods in the Autodesk.Revit.DB namespace provide access to shared parameters using the Revit API.
|
||||
|
||||
* DefinitionFile Class
|
||||
* Retrieved using the Application.OpenSharedParameterFile() method. Revit uses one shared parameter file at a time.
|
||||
* Represents one shared parameter file.
|
||||
* Contains a number of Group objects.
|
||||
* Shared parameters are grouped for easy management and contain shared parameter definitions.
|
||||
* New definitions can be added as needed.
|
||||
* ExternalDefinition Class
|
||||
* The ExternalDefinition object is created by a DefinitionGroup object from a shared parameter file.
|
||||
* External parameter definitions must belong to a Group which is a collection of shared parameter definitions.
|
||||
* Application.SharedParametersFilename Property
|
||||
* Get and set the shared parameter file path using this property.
|
||||
* By default, Revit does not have a shared parameter file.
|
||||
* Initialize this property before using. If it is not initialized, an exception is thrown.
|
||||
|
||||
|
||||
|
||||
### Create a Shared Parameter File
|
||||
|
||||
Because the definition file is a text file, it can be created manually or using code.
|
||||
|
||||
**Code Region 22-3: Creating a shared parameter file**
|
||||
---
|
||||
|
||||
|
||||
private void CreateExternalSharedParamFile(string sharedParameterFile)
|
||||
{
|
||||
System.IO.FileStream fileStream = System.IO.File.Create(sharedParameterFile);
|
||||
fileStream.Close();
|
||||
}
|
||||
|
||||
### Access an Existing Shared Parameter File
|
||||
|
||||
Since Revit can have many shared parameter files, it is necessary to specifically identify the file and external parameters you want to access. The following two procedures illustrate how to access an existing shared parameter file.
|
||||
|
||||
#### Get DefinitionFile from an External Parameter File
|
||||
|
||||
Set the shared parameter file path as the following code illustrates, then invoke the Application.OpenSharedParameterFile() method.
|
||||
|
||||
**Code Region 22-4: Getting the definition file from an external parameter file**
|
||||
---
|
||||
|
||||
|
||||
private DefinitionFile SetAndOpenExternalSharedParamFile(Autodesk.Revit.ApplicationServices.Application application, string sharedParameterFile)
|
||||
{
|
||||
// set the path of shared parameter file to current Revit
|
||||
application.SharedParametersFilename = sharedParameterFile;
|
||||
// open the file
|
||||
return application.OpenSharedParameterFile();
|
||||
}
|
||||
|
||||
Note: Consider the following points when you set the shared parameter path:
|
||||
|
||||
* During each installation, Revit cannot detect whether the shared parameter file was set in other versions. You must bind the shared parameter file for the new Revit installation again.
|
||||
* If Application.SharedParametersFilename is set to an invalid path, an exception is thrown only when OpenSharedParameterFile() is called.
|
||||
* Revit can work with multiple shared parameter files. Even though only one parameter file is used when loading a parameter, the current file can be changed freely.
|
||||
|
||||
|
||||
|
||||
#### Traverse All Parameter Entries
|
||||
|
||||
The following sample illustrates how to traverse the parameter entries and display the results in a message box.
|
||||
|
||||
**Code Region 22-5: Traversing parameter entries**
|
||||
---
|
||||
|
||||
|
||||
private void ShowDefinitionFileInfo(DefinitionFile myDefinitionFile)
|
||||
{
|
||||
StringBuilder fileInformation = new StringBuilder(500);
|
||||
|
||||
// get the file name
|
||||
fileInformation.AppendLine("File Name: " + myDefinitionFile.Filename);
|
||||
|
||||
// iterate the Definition groups of this file
|
||||
foreach (DefinitionGroup myGroup in myDefinitionFile.Groups)
|
||||
{
|
||||
// get the group name
|
||||
fileInformation.AppendLine("Group Name: " + myGroup.Name);
|
||||
|
||||
// iterate the difinitions
|
||||
foreach (Definition definition in myGroup.Definitions)
|
||||
{
|
||||
// get definition name
|
||||
fileInformation.AppendLine("Definition Name: " + definition.Name);
|
||||
}
|
||||
}
|
||||
TaskDialog.Show("Revit",fileInformation.ToString());
|
||||
}
|
||||
|
||||
### Change the Parameter Definition Owner Group
|
||||
|
||||
The following sample shows how to change the parameter definition group owner.
|
||||
|
||||
**Code Region 22-6: Changing parameter definition group owner**
|
||||
---
|
||||
|
||||
|
||||
private void ReadEditExternalParam(DefinitionFile file)
|
||||
{
|
||||
// get ExternalDefinition from shared parameter file
|
||||
DefinitionGroups myGroups = file.Groups;
|
||||
DefinitionGroup myGroup = myGroups.get_Item("MyGroup");
|
||||
if (myGroup != null)
|
||||
{
|
||||
ExternalDefinition myExtDef = myGroup.Definitions.get_Item("MyParam") as ExternalDefinition;
|
||||
if (myExtDef != null)
|
||||
{
|
||||
DefinitionGroup newGroup = myGroups.get_Item("AnotherGroup");
|
||||
if (newGroup != null)
|
||||
{
|
||||
// change the OwnerGroup of the ExternalDefinition
|
||||
myExtDef.OwnerGroup = newGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Shared Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_html.html)
|
||||
@@ -0,0 +1,67 @@
|
||||
# Shared Parameters
|
||||
|
||||
# Shared Parameters
|
||||
|
||||
Shared Parameters are parameter definitions stored in an external text file.
|
||||
|
||||
The definitions are identified by a unique identifier generated when the definition is created and can be used in multiple projects.
|
||||
|
||||
The main objects associated with shared parameters are:
|
||||
|
||||
* DefinitionFile - represents a shared parameters file on disk
|
||||
* DefinitionGroup - group of shared parameters which are organized into meaningful sets
|
||||
* ExternalDefinition - represents a shared parameter definition, belongs to a DefinitionGroup
|
||||
* ExternalDefinitions - supports the creation of new shared parameters definitions
|
||||
* Binding - binds a parameter definition to one or more categories
|
||||
* BindingMap - contains all the parameter bindings that exist in the Autodesk Revit project
|
||||
* ParameterElement - stores information about a particular user-defined parameter in the document
|
||||
* SharedParameterElement - derived from ParameterElement, stores the definition of a shared parameter The following sections describe how to gain access to shared parameter definitions through the Revit Platform API, including how to get a shared parameter definition and bind it to Elements in certain Categories.
|
||||
|
||||
|
||||
|
||||
To access Shared Parameters after they are defined and bound to categories, see [Built-In Parameters](Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Built_In_Parameters_html.html "Revit provides a general mechanism for giving each element a set of parameters that you can edit.").
|
||||
|
||||
## Clearing the value of a parameter
|
||||
|
||||
`Parameter.ClearValue()` resets the value of a shared parameter with the HideWhenNoValue flag to a cleared state. This method is not applicable to clear the value of any other parameter type.
|
||||
|
||||
### Hiding empty parameters
|
||||
|
||||
The property `ExternalDefinition.HideWhenNoValue` indicates if the shared parameter should be hidden from the property palette and `Element.GetOrderedParameters()` when it has no value.
|
||||
|
||||
This can be set when creating a shared parameter by setting `ExternalDefinitionCreationOptions.HideWhenNoValue` There is also `SharedParameterElement.ShouldHideWhenNoValue()`
|
||||
|
||||
### Filtering by presence or absence of parameter value
|
||||
|
||||
These filter classes define filter rules evaluating whether or not a parameter has a value for a specific element:
|
||||
|
||||
* ParameterValuePresenceRule
|
||||
* HasValueFilterRule
|
||||
* HasNoValueFilterRule
|
||||
|
||||
|
||||
|
||||
These static methods create an instance of these rules for use in a parameter filter.:
|
||||
|
||||
* FilterRule.CreateHasValueParameterRule()
|
||||
* FilterRule.CreateHasNoValueParameterRule()
|
||||
|
||||
|
||||
|
||||
In schedules, use these new enumerated values with the method `ScheduleDefinition.CanFilterByValuePresence()` to filter based on the presence or absence of a value assigned to that parameter:
|
||||
|
||||
* ScheduleFilterType.HasValue
|
||||
* ScheduleFilterType.HasNoValue
|
||||
|
||||
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Definition File](Shared_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_Definition_File_html.html)
|
||||
* [Working with the Definition File](Shared_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_Working_with_the_Definition_File_html.html)
|
||||
* [Binding](Shared_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_Binding_html.html)
|
||||
* [SharedParameterElement](Shared_Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_SharedParameterElement_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,84 @@
|
||||
# Walkthrough: Get Selected Element Parameters
|
||||
|
||||
# Walkthrough: Get Selected Element Parameters
|
||||
|
||||
The Element Parameters are retrieved by iterating through the Element ParameterSet. The following code sample illustrates how to retrieve the Parameter from a selected element.
|
||||
|
||||
Note: This example uses some Parameter members, such as AsValueString and StorageType, which are covered in subsequent topics.
|
||||
|
||||
**Code Region 8-1: Getting selected element parameters**
|
||||
---
|
||||
|
||||
|
||||
void GetElementParameterInformation(Document document, Element element)
|
||||
{
|
||||
// Format the prompt information string
|
||||
String prompt = "Show parameters in selected Element: \n\r";
|
||||
|
||||
StringBuilder st = new StringBuilder();
|
||||
// iterate element's parameters
|
||||
foreach (Parameter para in element.Parameters)
|
||||
{
|
||||
st.AppendLine(GetParameterInformation(para, document));
|
||||
}
|
||||
|
||||
// Give the user some information
|
||||
TaskDialog.Show("Revit", prompt + st.ToString());
|
||||
}
|
||||
|
||||
String GetParameterInformation(Parameter para, Document document)
|
||||
{
|
||||
string defName = para.Definition.Name + "\t : ";
|
||||
string defValue = string.Empty;
|
||||
// Use different method to get parameter data according to the storage type
|
||||
switch (para.StorageType)
|
||||
{
|
||||
case StorageType.Double:
|
||||
//covert the number into Metric
|
||||
defValue = para.AsValueString();
|
||||
break;
|
||||
case StorageType.ElementId:
|
||||
//find out the name of the element
|
||||
Autodesk.Revit.DB.ElementId id = para.AsElementId();
|
||||
if (id.Value >= 0)
|
||||
{
|
||||
defValue = document.GetElement(id).Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
defValue = id.Value.ToString();
|
||||
}
|
||||
break;
|
||||
case StorageType.Integer:
|
||||
if (SpecTypeId.Boolean.YesNo == para.Definition.GetDataType())
|
||||
{
|
||||
if (para.AsInteger() == 0)
|
||||
{
|
||||
defValue = "False";
|
||||
}
|
||||
else
|
||||
{
|
||||
defValue = "True";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
defValue = para.AsInteger().ToString();
|
||||
}
|
||||
break;
|
||||
case StorageType.String:
|
||||
defValue = para.AsString();
|
||||
break;
|
||||
default:
|
||||
defValue = "Unexposed parameter.";
|
||||
break;
|
||||
}
|
||||
|
||||
return defName + defValue;
|
||||
}
|
||||
|
||||
**Figure 26: Get wall parameters result**
|
||||
|
||||
Note: In Revit, some parameters have values in the drop-down list in the Element Properties dialog box. You can get the numeric values corresponding to the enumerated type for the Parameter using the Revit Platform API, but you cannot get the string representation for the values using the Parameter.AsValueString() method.
|
||||
|
||||
**Parent page:** [Parameters](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_html.html)
|
||||
@@ -0,0 +1,66 @@
|
||||
# Parameters
|
||||
|
||||
# Parameters
|
||||
|
||||
Revit provides a general mechanism for giving each element a set of parameters that you can edit.
|
||||
|
||||
In the Revit UI, some element parameters are visible in the Element Properties Palette. The following sections describe how to get and use built-in parameters, shared parameters and global parameters.
|
||||
|
||||
In the Revit Platform API, Parameters are managed in the Element class. You can access Parameters in these ways:
|
||||
|
||||
Common ways to get the value of a parameter are shown below. In this sample, all three lines of code get the same parameter. Because this parameter is stored as a string, the `AsString()` method is used to get its value.
|
||||
|
||||
|
||||
private void GetStringParameterValue(Wall wall)
|
||||
{
|
||||
string s1 = wall.LookupParameter("Comments").AsString();
|
||||
string s2 = wall.GetParameter(ParameterTypeId.AllModelInstanceComments).AsString();
|
||||
string s3 = wall.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsString();
|
||||
}
|
||||
|
||||
Other ways to get a parameter are:
|
||||
|
||||
* By iterating through the Element.Parameters collection of all parameters for an Element (for an example, see the sample code in [Walkthrough Get Selected Element Parameters](./Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Walkthrough_Get_Selected_Element_Parameters_html.html)).
|
||||
* By iterating through the collection returned by Element.GetOrderedParameters(), which returns only parameters visible in the Properties Palette.
|
||||
* By accessing a parameter by name via the Element.ParametersMap collection or Element.GetParameters().
|
||||
|
||||
|
||||
|
||||
You can retrieve the Parameter object from an Element using the overloaded Parameter property if you know the built-in ID, definition, or GUID. The Parameter[GUID] property overload gets a shared parameter based on its Global Unique ID (GUID), which is assigned to the shared parameter when it's created.
|
||||
|
||||
The Element.LookupParameter() method gets a parameter based on its localized name, so your code should handle different languages if it's going to look up parameters by name and needs to run in more than one locale. Also, keep in mind that multiple matches of parameters with the same name can occur because shared parameters or project parameters can be bound to an element category even if there is already a built-in parameter with the same name. For this reason, it is better to use Element.GetParameters() which will return all parameters matching the given name. Element.LookupParameter() will return the first match found.
|
||||
|
||||
## Parameters Service
|
||||
|
||||
Parameters Service is a semi-automated, fully searchable database of design element parameters. Because Parameters Service lives in the Autodesk Construction Cloud, you can easily share it with teammates regardless of their physical location.
|
||||
|
||||
The class `Autodesk.Revit.DB.ParameterDownloadOptions` is an option class used for downloading parameters from the Parameters Service with the following properties:
|
||||
|
||||
* ParameterDownloadOptions.Categories - Categories for binding.
|
||||
* ParameterDownloadOptions.IsInstance - Returns true if binding to element instances, false if binding to element types.
|
||||
* ParameterDownloadOptions.Visible - Returns true if the parameter is visible to the user, false if it is hidden and accessible only via the API.
|
||||
* ParameterDownloadOptions.GroupTypeId - Properties palette group identifier.
|
||||
|
||||
|
||||
|
||||
These `ParameterUtils` methods provide functionality relevant to the Parameters Service:
|
||||
|
||||
* ParameterUtils.DownloadParameter() - Allows users to create a shared parameter element in the given document according to a parameter definition downloaded from the Parameters Service.
|
||||
* ParameterUtils.DownloadParameterOptions() - Allows users to retrieve the requested parameter's category, visibility and group bindings from the Forge Schema Service.
|
||||
* ParameterUtils.DownloadCompanyName() - Allows users to download and record the name of the given parameter schema identifier's owning account in the given document.
|
||||
|
||||
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Walkthrough: Get Selected Element Parameters](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Walkthrough_Get_Selected_Element_Parameters_html.html)
|
||||
* [Parameter](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Parameter_html.html)
|
||||
* [Definition](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Definition_html.html)
|
||||
* [Built-In Parameters](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Built_In_Parameters_html.html)
|
||||
* [Parameter Relationships](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Parameter_Relationships_html.html)
|
||||
* [Shared Parameters](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Shared_Parameters_html.html)
|
||||
* [Global Parameters](Parameters/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Parameters_Global_Parameters_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,55 @@
|
||||
# Changing the Selection
|
||||
|
||||
# Changing the Selection
|
||||
|
||||
To modify the selected elements:
|
||||
|
||||
1. Create a new List of ElementIds.
|
||||
2. Put ElementIds in it.
|
||||
3. Call SetElementIds() with the new list.
|
||||
|
||||
|
||||
|
||||
The following example illustrates how to change the selected Elements by getting the current selection and filtering out just walls to set as the new selection.
|
||||
|
||||
It is also possible to select references by using `SetReferences()`. The references can be an element or a sub element in the host or a linked document. `GetReferences()` returns the references that are currently selected.
|
||||
|
||||
**Code Region 7-1: Changing selected elements**
|
||||
---
|
||||
|
||||
|
||||
private void ChangeSelection(UIDocument uidoc)
|
||||
{
|
||||
// Get selected elements from current document.
|
||||
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
|
||||
|
||||
// Display current number of selected elements
|
||||
TaskDialog.Show("Revit", "Number of selected elements: " + selectedIds.Count.ToString());
|
||||
|
||||
// Go through the selected items and filter out walls only.
|
||||
ICollection<ElementId> selectedWallIds = new List<ElementId>();
|
||||
|
||||
foreach (ElementId id in selectedIds)
|
||||
{
|
||||
Element elements = uidoc.Document.GetElement(id);
|
||||
if (elements is Wall)
|
||||
{
|
||||
selectedWallIds.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the created element set as current select element set.
|
||||
uidoc.Selection.SetElementIds(selectedWallIds);
|
||||
|
||||
// Give the user some information.
|
||||
if (0 != selectedWallIds.Count)
|
||||
{
|
||||
TaskDialog.Show("Revit", selectedWallIds.Count.ToString() + " Walls are selected!");
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskDialog.Show("Revit","No Walls have been selected!");
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Selection](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_html.html)
|
||||
@@ -0,0 +1,79 @@
|
||||
# Filtered User Selection
|
||||
|
||||
# Filtered User Selection
|
||||
|
||||
PickObject(), PickObjects() and PickElementsByRectangle() all have overloads that take an ISelectionFilter as a parameter. ISelectionFilter is an interface that can be implemented to filter objects during a selection operation. It has two methods that can be overridden: AllowElement() which is used to specify if an element is allowed to be selected, and AllowReference() which is used to specify if a reference to a piece of geometry is allowed to be selected.
|
||||
|
||||
The following example illustrates how to use an ISelectionFilter interface to limit the user's selection to elements in the Mass category. It does not allow any references to geometry to be selected.
|
||||
|
||||
**Code Region 7-4: Using ISelectionFilter to limit element selection**
|
||||
---
|
||||
|
||||
|
||||
public static IList<Element> GetManyRefByRectangle(UIDocument doc)
|
||||
{
|
||||
ReferenceArray ra = new ReferenceArray();
|
||||
ISelectionFilter selFilter = new MassSelectionFilter();
|
||||
IList<Element> eList = doc.Selection.PickElementsByRectangle(selFilter,
|
||||
"Select multiple faces") as IList<Element>;
|
||||
return eList;
|
||||
}
|
||||
|
||||
public class MassSelectionFilter : ISelectionFilter
|
||||
{
|
||||
public bool AllowElement(Element element)
|
||||
{
|
||||
if (element.Category.Name == "Mass")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AllowReference(Reference refer, XYZ point)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
The next example demonstrates the use of ISelectionFilter to allow only planar faces to be selected.
|
||||
|
||||
**Code Region 7-5: Using ISelectionFilter to limit geometry selection**
|
||||
---
|
||||
|
||||
|
||||
public void SelectPlanarFaces(Autodesk.Revit.DB.Document document)
|
||||
{
|
||||
UIDocument uidoc = new UIDocument(document);
|
||||
ISelectionFilter selFilter = new PlanarFacesSelectionFilter(document);
|
||||
IList<Reference> faces = uidoc.Selection.PickObjects(ObjectType.Face,
|
||||
selFilter, "Select multiple planar faces");
|
||||
}
|
||||
|
||||
public class PlanarFacesSelectionFilter : ISelectionFilter
|
||||
{
|
||||
Document doc = null;
|
||||
public PlanarFacesSelectionFilter(Document document)
|
||||
{
|
||||
doc = document;
|
||||
}
|
||||
|
||||
public bool AllowElement(Element element)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AllowReference(Reference refer, XYZ point)
|
||||
{
|
||||
if (doc.GetElement(refer).GetGeometryObjectFromReference(refer) is PlanarFace)
|
||||
{
|
||||
// Only return true for planar faces. Non-planar faces will not be selectable
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
For more information about retrieving Elements from selected Elements, see [Walkthrough: Retrieve Selected Elements](../../Introduction/Getting_Started/Revit_API_Revit_API_Developers_Guide_Introduction_Getting_Started_Walkthrough_Retrieve_Selected_Elements_html.html) in the [Getting Started](../../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Getting_Started_html.html) section.
|
||||
|
||||
**Parent page:** [Selection](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_html.html)
|
||||
@@ -0,0 +1,117 @@
|
||||
# User Selection
|
||||
|
||||
# User Selection
|
||||
|
||||
The Selection class also has methods for allowing the user to select new objects, or even a point on screen. This allows the user to select one or more Elements (or other objects, such as an edge or a face) using the cursor and then returns control to your application. These functions do not automatically add the new selection to the active selection collection.
|
||||
|
||||
* The PickObject() method prompts the user to select an object in the Revit model.
|
||||
* The PickObjects() method prompts the user to select multiple objects in the Revit model.
|
||||
* The PickElementsByRectangle() method prompts the user to select multiple elements using a rectangle.
|
||||
* The PickPoint() method prompts the user to pick a point in the active sketch plane.
|
||||
* The PickBox() method invokes a general purpose two-click editor that lets the user to specify a rectangular area on the screen.
|
||||
|
||||
|
||||
|
||||
The type of object to be selected is specified when calling PickObject() or PickObjects. Types of objects that can be specified are: Element, PointOnElement, Edge or Face.
|
||||
|
||||
The StatusbarTip property shows a message in the status bar when your application prompts the user to pick objects or elements. Each of the Pick functions has an overload that has a String parameter in which a custom status message can be provided.
|
||||
|
||||
**Code Region 7-2: Adding selected elements with PickObject() and PickElementsByRectangle()**
|
||||
---
|
||||
|
||||
|
||||
public void SelectElements(Document document)
|
||||
{
|
||||
UIDocument uidoc = new UIDocument(document);
|
||||
Selection choices = uidoc.Selection;
|
||||
// Pick one object from Revit.
|
||||
Reference hasPickOne = choices.PickObject(ObjectType.Element);
|
||||
if (hasPickOne != null)
|
||||
{
|
||||
TaskDialog.Show("Revit", "One element selected.");
|
||||
}
|
||||
|
||||
// Use the rectangle picking tool to identify model elements to select.
|
||||
IList<Element> pickedElements = uidoc.Selection.PickElementsByRectangle("Select by rectangle");
|
||||
if (pickedElements.Count > 0)
|
||||
{
|
||||
// Collect Ids of all picked elements
|
||||
IList<ElementId> idsToSelect = new List<ElementId>(pickedElements.Count);
|
||||
foreach (Element element in pickedElements)
|
||||
{
|
||||
idsToSelect.Add(element.Id);
|
||||
}
|
||||
|
||||
// Update the current selection
|
||||
uidoc.Selection.SetElementIds(idsToSelect);
|
||||
TaskDialog.Show("Revit", string.Format("{0} elements added to Selection.", idsToSelect.Count));
|
||||
}
|
||||
}
|
||||
|
||||
The PickPoint() method has 2 overloads with an ObjectSnapTypes parameter which is used to specify the type of snap types used for the selection. More than one can be specified, as shown in the next example.
|
||||
|
||||
**Code Region 7-3: Snap points**
|
||||
---
|
||||
|
||||
|
||||
public void PickPoint(UIDocument uidoc)
|
||||
{
|
||||
|
||||
ObjectSnapTypes snapTypes = ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections;
|
||||
XYZ point = uidoc.Selection.PickPoint(snapTypes, "Select an end point or intersection");
|
||||
|
||||
string strCoords = "Selected point is " + point.ToString();
|
||||
|
||||
TaskDialog.Show("Revit", strCoords);
|
||||
}
|
||||
|
||||
The PickBox() method takes a PickBoxStyle enumerator. The options are Crossing, the style used when selecting objects completely or partially inside the box, Enclosing, the style used selecting objects that are completely enclosed by the box, and Directional, in which the style of the box depends on the direction in which the box is being drawn. It uses the Crossing style if it is being drawn from right to left, or the Enclosing style when drawn in the opposite direction.
|
||||
|
||||
PickBox() returns a PickedBox which contains the Min and Max points selected. The following example demonstrates the use of PickBox() in Point Cloud selection.
|
||||
|
||||
**Code Region: PickBox**
|
||||
---
|
||||
|
||||
|
||||
public void PromptForPointCloudSelection(UIDocument uiDoc, PointCloudInstance pcInstance)
|
||||
{
|
||||
Autodesk.Revit.ApplicationServices.Application app = uiDoc.Application.Application;
|
||||
Selection currentSel = uiDoc.Selection;
|
||||
|
||||
PickedBox pickedBox = currentSel.PickBox(PickBoxStyle.Enclosing, "Select region of cloud for highlighting");
|
||||
|
||||
XYZ min = pickedBox.Min;
|
||||
XYZ max = pickedBox.Max;
|
||||
|
||||
//Transform points into filter
|
||||
View view = uiDoc.ActiveView;
|
||||
XYZ right = view.RightDirection;
|
||||
XYZ up = view.UpDirection;
|
||||
|
||||
List<Plane> planes = new List<Plane>();
|
||||
|
||||
// X boundaries
|
||||
bool directionCorrect = IsPointAbovePlane(right, min, max);
|
||||
planes.Add(Plane.CreateByNormalAndOrigin(right, directionCorrect ? min : max));
|
||||
planes.Add(Plane.CreateByNormalAndOrigin(-right, directionCorrect ? max : min));
|
||||
|
||||
// Y boundaries
|
||||
directionCorrect = IsPointAbovePlane(up, min, max);
|
||||
planes.Add(Plane.CreateByNormalAndOrigin(up, directionCorrect ? min : max));
|
||||
planes.Add(Plane.CreateByNormalAndOrigin(-up, directionCorrect ? max : min));
|
||||
|
||||
// Create filter
|
||||
PointCloudFilter filter = PointCloudFilterFactory.CreateMultiPlaneFilter(planes);
|
||||
Transaction t = new Transaction(uiDoc.Document, "Highlight");
|
||||
t.Start();
|
||||
pcInstance.SetSelectionFilter(filter);
|
||||
pcInstance.FilterAction = SelectionFilterAction.Highlight;
|
||||
t.Commit();
|
||||
uiDoc.RefreshActiveView();
|
||||
}
|
||||
|
||||
## Selection Events
|
||||
|
||||
The `SelectionChanged` event notifies your code after the selection changes. `SelectionChangedEventArgs` provides access to the references and element ids that are selected.
|
||||
|
||||
**Parent page:** [Selection](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_html.html)
|
||||
@@ -0,0 +1,36 @@
|
||||
# Selection
|
||||
|
||||
# Selection
|
||||
|
||||
You can get the selected objects from the current active document using the UIDocument.Selection.GetElementIds() method which returns a collection of ElementIds of the selected elements. The collection returned by this method can be used directly with FilteredElementCollector to filter the selected elements.
|
||||
|
||||
The Selection object can also be used to change the current selection programmatically using the SetElementIds() method.
|
||||
|
||||
## PickPoint
|
||||
|
||||
The `Selection.PickPoint()` method prompts the user to pick a point on the active work plane. By specifying one or more value from the `ObjectSnapTypes` enum, you can determine which objects the user's cursor will snap to during the pick. These values are
|
||||
|
||||
* Centers
|
||||
* CoordinationModelPoints
|
||||
* Endpoints
|
||||
* Intersections
|
||||
* Midpoints
|
||||
* Nearest
|
||||
* None
|
||||
* Perpendicular
|
||||
* Points
|
||||
* Quadrants
|
||||
* Tangents
|
||||
* WorkPlaneGrid
|
||||
|
||||
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Changing the Selection](Selection/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_Changing_the_Selection_html.html)
|
||||
* [User Selection](Selection/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_User_Selection_html.html)
|
||||
* [Filtered User Selection](Selection/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Selection_Filtered_User_Selection_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,40 @@
|
||||
# Failure Handling Options
|
||||
|
||||
# Failure Handling Options
|
||||
|
||||
Failure handling options are options for how failures, if any, should be handled at the end of a transaction. Failure handling options may be set at any time before calling either Transaction.Commit() or Transaction.RollBack() using the Transaction.SetFailureHandlingOptions() method. However, after a transaction is committed or rolled back, the options return to their respective default settings.
|
||||
|
||||
The SetFailureHandlingOptions() method takes a FailureHandlingOptions object as a parameter. This object cannot be created, it must be obtained from the transaction using the GetFailureHandlingOptions() method. Options are set by calling the corresponding Set method, such as SetClearAfterRollback(). The following sections discuss the failure handling options in more detail.
|
||||
|
||||
### ClearAfterRollback
|
||||
|
||||
This option controls whether all warnings should be cleared after a transaction is rolled back. The default value is False.
|
||||
|
||||
### DelayedMiniWarnings
|
||||
|
||||
This options controls whether mini-warnings, if any, are displayed at the end of the transaction currently being ended, or if they should be postponed until the end of next transaction. This is typically used within a chain of transactions when it is not desirable to show intermediate warnings at the end of each step, but rather to wait until the completion of the entire chain.
|
||||
|
||||
Warnings may be delayed for more than one transaction. The first transaction that does not have this option set to True will display all of its own warnings, if any, as well as all warnings that might have accumulated from previous transactions. The default value is False.
|
||||
|
||||
Note: This option is ignored in modal mode (see ForcedModalHandling below).
|
||||
|
||||
### ForcedModalHandling
|
||||
|
||||
This options controls whether eventual failures will be handled modally or modelessly. The default is True. Be aware that if the modeless failure handling is set, processing the transaction may be done asynchronously, which means that upon returning from the Commit or RollBack calls, the transaction will not be finished yet (the status will be 'Pending').
|
||||
|
||||
### SetFailuresPreprocessor
|
||||
|
||||
This interface, if provided, is invoked when there are failures found at the end of a transaction. The preprocessor may examine current failures and even try to resolve them. See [Failure Posting and Handling](../../Advanced_Topics/Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Failure_Posting_and_Handling_html.html) for more information.
|
||||
|
||||
### SetTransactionFinalizer
|
||||
|
||||
A finalizer is an interface, which, if provided, can be used to perform a custom action at the end of a transaction. Note that it is not invoked when the Commit() or RollBack() methods are called, but only after the process of committing or rolling back is completed. Transaction finalizers must implement the _ITransactionFinalizer_ interface, which requires two functions to be defined:
|
||||
|
||||
* OnCommitted - called at the end of committing a transaction
|
||||
* OnRolledBack - called at the end of rolling back a transaction
|
||||
|
||||
|
||||
|
||||
Note: Since the finalizer is called after the transaction has finished, the document is not modifiable from the finalizer unless a new transaction is started.
|
||||
|
||||
**Parent page:** [Transactions](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_html.html)
|
||||
@@ -0,0 +1,70 @@
|
||||
# Getting Element Geometry and AnalyticalElement
|
||||
|
||||
# Getting Element Geometry and AnalyticalElement
|
||||
|
||||
After new elements are created or elements are modified, regeneration and auto-joining of elements is required to propagate the changes throughout the model. Without a regeneration (and auto-join, when relevant), the Geometry property and the AnalyticalElement for Elements are either unobtainable (in the case of creating a new element) or they may be invalid. It is important to understand how and when regeneration occurs before accessing the Geometry or AnalyticalElement of an Element.
|
||||
|
||||
### Connectors in Structural Analytical Elements
|
||||
|
||||
The property:
|
||||
|
||||
* AnalyticalElement.ConnectorManager retrieves the connector manager of a given structural analytical element. It will return connectors of Domain.StructuralAnalytical.
|
||||
|
||||
|
||||
|
||||
### Points in Structural Analytical networks
|
||||
|
||||
The method Hub.GetPointId() returns the id of the associated Point element.
|
||||
|
||||
Although regeneration and auto-join are necessary to propagate changes made in the model, it can be time consuming. It is best if these events occur only as often as necessary.
|
||||
|
||||
Regeneration and auto-joining occur automatically when a transaction that modifies the model is committed successfully, or whenever the Document.Regenerate() or Document.AutoJoinElements() methods are called. Regenerate() and AutoJoinElements() may only be called inside an open transaction. It should be noted that the Regeneration() method can fail, in which case the RegenerationFailedException will be thrown. If this happens, the changes to the document need to be rolled back by rolling back the current transaction or subtransaction.
|
||||
|
||||
The method StructuralSettings.BoundarySetbackDisabledForSteelElements() allows users to disable the auto-join setback distances for all structural steel framing, slanted columns, trusses, beam systems and braces.
|
||||
|
||||
For more information, see [Analytical Model](../../Discipline_Specific_Functionality/Structural_Engineering/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_Analytical_Model_html.html) and [Geometry](../../Revit_Geometric_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html).
|
||||
|
||||
The following sample program demonstrates how a transaction populates these properties:
|
||||
|
||||
**Code Region 23-3: Transaction populating Geometry and AnalyticalPanel properties**
|
||||
---
|
||||
|
||||
|
||||
public void TransactionDuringElementCreation(UIApplication uiApplication, Level level)
|
||||
{
|
||||
Autodesk.Revit.DB.Document document = uiApplication.ActiveUIDocument.Document;
|
||||
|
||||
// Build a location line for the wall creation
|
||||
XYZ start = new XYZ(0, 0, 0);
|
||||
XYZ end = new XYZ(10, 10, 0);
|
||||
Autodesk.Revit.DB.Line geomLine = Line.CreateBound(start, end);
|
||||
|
||||
// All and any transaction should be enclosed in a 'using'
|
||||
// block or guarded within a try-catch-finally blocks
|
||||
// to guarantee that a transaction does not out-live its scope.
|
||||
using (Transaction wallTransaction = new Transaction(document, "Creating wall"))
|
||||
{
|
||||
// To create a wall, a transaction must be first started
|
||||
if (wallTransaction.Start() == TransactionStatus.Started)
|
||||
{
|
||||
// Create a wall using the location line
|
||||
Wall wall = Wall.Create(document, geomLine, level.Id, true);
|
||||
|
||||
// the transaction must be committed before you can
|
||||
// get the value of Geometry and AnalyticalPanel.
|
||||
|
||||
if (wallTransaction.Commit() == TransactionStatus.Committed)
|
||||
{
|
||||
Autodesk.Revit.DB.Options options = uiApplication.Application.Create.NewGeometryOptions();
|
||||
Autodesk.Revit.DB.GeometryElement geoelem = wall.get_Geometry(options);
|
||||
Autodesk.Revit.DB.Structure.AnalyticalPanel analyticalPanel = (AnalyticalPanel)document.GetElement(AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document).GetAssociatedElementId(wall.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The transaction timeline for this sample is as follows:
|
||||
|
||||
**Figure 134: Transaction timeline**
|
||||
|
||||
**Parent page:** [Transactions](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_html.html)
|
||||
@@ -0,0 +1,22 @@
|
||||
# Temporary transactions
|
||||
|
||||
# Temporary transactions
|
||||
|
||||
It is not always required to commit a transaction. The transaction framework also allows for Trasactions to be rolled back. This is useful when there is an error during the processing of the transaction, but can also be leverage directly as a technique to create a temporary transaction.
|
||||
|
||||
Using a temporary transaction can be useful for certain types of analyses. For example, an application looking to extract geometric properties from a wall or other object before it is cut by openings should use a temporary transaction in conjunction with Document.Delete(). When the application deletes the elements that cut the target elements, the cut element’s geometry is restored to its original state (after the document has been regenerated).
|
||||
|
||||
To use a temporary transaction:
|
||||
|
||||
1. Instantiate the Transaction using the Transaction constructor, and assign it a name.
|
||||
2. Call Transaction.Start().
|
||||
3. Make the temporary change(s) to the document (element modification, deletion or creation).
|
||||
4. Regenerate the document.
|
||||
5. Extract the desired geometry and properties.
|
||||
6. Call Transaction.RollBack() to restore the document to the previous state.
|
||||
|
||||
|
||||
|
||||
This technique is also applicable to SubTransactions.
|
||||
|
||||
**Parent page:** [Transactions](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_html.html)
|
||||
@@ -0,0 +1,206 @@
|
||||
# Transaction Classes
|
||||
|
||||
# Transaction Classes
|
||||
|
||||
All three transaction objects share some common methods:
|
||||
|
||||
**Table 51: Common Transaction Object Methods**
|
||||
|
||||
**Method** | **Description**
|
||||
---|---
|
||||
Start | Will start the context
|
||||
Commit | Ends the context and commits all changes to the document
|
||||
Rollback | Ends the context and discards all changes to the document
|
||||
GetStatus | Returns the current status of the transaction object
|
||||
|
||||
In addition to the GetStatus() method returning the current status, the Start, Commit and RollBack methods also return a TransactionStatus indicating whether or not the method was successful. Available TransactionStatus values include:
|
||||
|
||||
**Table 52: TransactionStatus values**
|
||||
|
||||
**Status** | **Description**
|
||||
---|---
|
||||
Uninitialized | The initial value after object is instantiated; the context has not started yet
|
||||
Started | Transaction object has successfully started (Start was called)
|
||||
RolledBack | Transaction object was successfully rolled back (Rollback was called)
|
||||
Committed | Transaction object was successfully committed (Commit was called)
|
||||
Pending | Transaction object was attempted to be either submitted or rolled back, but due to failures that process could not be finished yet and is waiting for the end-user's response (in a modeless dialog). Once the failure processing is finished, the status will be automatically updated (to either Committed or RolledBack status).
|
||||
|
||||
### Transaction
|
||||
|
||||
A transaction is a context required in order to make any changes to a Revit model. Only one transaction can be open at a time; nesting is not allowed. Each transaction must have a name, which will be listed on the Undo menu in Revit once a transaction is successfully committed.
|
||||
|
||||
**Code Region 23-1: Using transactions**
|
||||
---
|
||||
|
||||
|
||||
public void CreatingModelLines(UIApplication uiApplication)
|
||||
{
|
||||
Autodesk.Revit.DB.Document document = uiApplication.ActiveUIDocument.Document;
|
||||
Autodesk.Revit.ApplicationServices.Application application = uiApplication.Application;
|
||||
|
||||
// Create a few geometry lines. These lines are not elements,
|
||||
// therefore they do not need to be created inside a document transaction.
|
||||
XYZ Point1 = XYZ.Zero;
|
||||
XYZ Point2 = new XYZ(10, 0, 0);
|
||||
XYZ Point3 = new XYZ(10, 10, 0);
|
||||
XYZ Point4 = new XYZ(0, 10, 0);
|
||||
|
||||
Line geomLine1 = Line.CreateBound(Point1, Point2);
|
||||
Line geomLine2 = Line.CreateBound(Point4, Point3);
|
||||
Line geomLine3 = Line.CreateBound(Point1, Point4);
|
||||
|
||||
// This geometry plane is also transaction and does not need a transaction
|
||||
XYZ origin = XYZ.Zero;
|
||||
XYZ normal = new XYZ(0, 0, 1);
|
||||
Plane geomPlane = Plane.CreateByNormalAndOrigin(normal, origin);
|
||||
|
||||
// In order to a sketch plane with model curves in it, we need
|
||||
// to start a transaction because such operations modify the model.
|
||||
|
||||
// All and any transaction should be enclosed in a 'using'
|
||||
// block or guarded within a try-catch-finally blocks
|
||||
// to guarantee that a transaction does not out-live its scope.
|
||||
using (Transaction transaction = new Transaction(document))
|
||||
{
|
||||
if (transaction.Start("Create model curves") == TransactionStatus.Started)
|
||||
{
|
||||
// Create a sketch plane in current document
|
||||
SketchPlane sketch = SketchPlane.Create(document,geomPlane);
|
||||
|
||||
// Create a ModelLine elements using the geometry lines and sketch plane
|
||||
ModelLine line1 = document.Create.NewModelCurve(geomLine1, sketch) as ModelLine;
|
||||
ModelLine line2 = document.Create.NewModelCurve(geomLine2, sketch) as ModelLine;
|
||||
ModelLine line3 = document.Create.NewModelCurve(geomLine3, sketch) as ModelLine;
|
||||
|
||||
// Ask the end user whether the changes are to be committed or not
|
||||
TaskDialog taskDialog = new TaskDialog("Revit");
|
||||
taskDialog.MainContent = "Click either [OK] to Commit, or [Cancel] to Roll back the transaction.";
|
||||
TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel;
|
||||
taskDialog.CommonButtons = buttons;
|
||||
|
||||
if (TaskDialogResult.Ok == taskDialog.Show())
|
||||
{
|
||||
// For many various reasons, a transaction may not be committed
|
||||
// if the changes made during the transaction do not result a valid model.
|
||||
// If committing a transaction fails or is canceled by the end user,
|
||||
// the resulting status would be RolledBack instead of Committed.
|
||||
if (TransactionStatus.Committed != transaction.Commit())
|
||||
{
|
||||
TaskDialog.Show("Failure", "Transaction could not be committed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### SubTransaction
|
||||
|
||||
A SubTransaction can be used to enclose a set of model-modifying operations. Sub-transactions are optional. They are not required in order to modify the model. They are a convenience tool to allow logical splitting of larger tasks into smaller ones. Sub-transactions can only be created within an already opened transaction and must be closed (either committed or rolled back) before the transaction is closed (committed or rolled back). Unlike transactions, sub-transaction may be nested, but any nested sub-transaction must be closed before the enclosing sub-transaction is closed. Sub-transactions do not have a name, for they do not appear on the Undo menu in Revit.
|
||||
|
||||
### TransactionGroup
|
||||
|
||||
TransactionGroup allows grouping together several independent transactions, which gives the owner of a group an opportunity to address many transactions at once. When a transaction group is to be closed, it can be rolled back, which means that all previously committed transactions belonging to the group will be rolled back. If not rolled back, a group can be either committed or assimilated. In the former case, all committed transactions (within the group) will be left as they were. In the later case, transactions within the group will be merged together into one single transaction that will bear the group's name.
|
||||
|
||||
A transaction group can only be started when there is no transaction open yet, and must be closed only after all enclosed transactions are closed (rolled back or committed). Transaction groups can be nested, but any nested group must be closed before the enclosing group is closed. Transaction groups are optional. They are not required in order to make modifications to a model.
|
||||
|
||||
The following example shows the use of a TransactionGroup to combine two separate Transactions using the Assimilate() method. The following code will result in a single Undo item added to the Undo menu with the name "Level and Grid".
|
||||
|
||||
**Code Region 23-2: Combining multiple transactions into a TransactionGroup**
|
||||
---
|
||||
|
||||
|
||||
public void CompoundOperation(Autodesk.Revit.DB.Document document)
|
||||
{
|
||||
// All and any transaction group should be enclosed in a 'using' block or guarded within
|
||||
// a try-catch-finally blocks to guarantee that the group does not out-live its scope.
|
||||
using (TransactionGroup transGroup = new TransactionGroup(document, "Level and Grid"))
|
||||
{
|
||||
if (transGroup.Start() == TransactionStatus.Started)
|
||||
{
|
||||
// We are going to call two methods, each having its own local transaction.
|
||||
// For our compound operation to be considered successful, both the individual
|
||||
// transactions must succeed. If either one fails, we will roll our group back,
|
||||
// regardless of what transactions might have already been committed.
|
||||
|
||||
if (CreateLevel(document, 25.0) && CreateGrid(document, new XYZ(0,0,0), new XYZ(10,0,0)))
|
||||
{
|
||||
// The process of assimilating will merge the two (or any number of) committed
|
||||
// transaction together and will assign the grid's name to the one resulting transaction,
|
||||
// which will become the only item from this compound operation appearing in the undo menu.
|
||||
transGroup.Assimilate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since we could not successfully finish at least one of the individual
|
||||
// operation, we are going to roll the entire group back, which will
|
||||
// undo any transaction already committed while this group was open.
|
||||
transGroup.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CreateLevel(Autodesk.Revit.DB.Document document, double elevation)
|
||||
{
|
||||
// All and any transaction should be enclosed in a 'using'
|
||||
// block or guarded within a try-catch-finally blocks
|
||||
// to guarantee that a transaction does not out-live its scope.
|
||||
using (Transaction transaction = new Transaction(document, "Creating Level"))
|
||||
{
|
||||
// Must start a transaction to be able to modify a document
|
||||
|
||||
if( TransactionStatus.Started == transaction.Start())
|
||||
{
|
||||
if (null != Level.Create(document, elevation))
|
||||
{
|
||||
// For many various reasons, a transaction may not be committed
|
||||
// if the changes made during the transaction do not result a valid model.
|
||||
// If committing a transaction fails or is canceled by the end user,
|
||||
// the resulting status would be RolledBack instead of Committed.
|
||||
return (TransactionStatus.Committed == transaction.Commit());
|
||||
}
|
||||
|
||||
// For we were unable to create the level, we will roll the transaction back
|
||||
// (although on this simplified case we know there weren't any other changes)
|
||||
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CreateGrid(Autodesk.Revit.DB.Document document, XYZ p1, XYZ p2)
|
||||
{
|
||||
// All and any transaction should be enclosed in a 'using'
|
||||
// block or guarded within a try-catch-finally blocks
|
||||
// to guarantee that a transaction does not out-live its scope.
|
||||
using (Transaction transaction = new Transaction(document, "Creating Grid"))
|
||||
{
|
||||
// Must start a transaction to be able to modify a document
|
||||
if (TransactionStatus.Started == transaction.Start())
|
||||
{
|
||||
// We create a line and use it as an argument to create a grid
|
||||
Line gridLine = Line.CreateBound(p1, p2);
|
||||
|
||||
if ((null != gridLine) && (null != Grid.Create(document, gridLine)))
|
||||
{
|
||||
if (TransactionStatus.Committed == transaction.Commit())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// For we were unable to create the grid, we will roll the transaction back
|
||||
// (although on this simplified case we know there weren't any other changes)
|
||||
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
**Parent page:** [Transactions](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_html.html)
|
||||
@@ -0,0 +1,15 @@
|
||||
# Transactions in Events
|
||||
|
||||
# Transactions in Events
|
||||
|
||||
### Modifying the document during an event
|
||||
|
||||
Events do not automatically open transactions. Therefore, the document will not be modified during an event unless one of the event's handlers modifies it by making changes inside a transaction. If an event handler opens a transaction it is required that it will also close it (commit it or roll it back), otherwise all changes will be discarded.
|
||||
|
||||
Please be aware that modifying the active document is not permitted during some events (e.g., the DocumentClosing event). If an event handler attempts to make modifications during such an event, an exception will be thrown. The event documentation indicates whether or not the event is read-only.
|
||||
|
||||
### DocumentChanged Event
|
||||
|
||||
The DocumentChanged event is raised after every transaction gets committed, undone, or redone. This is a read-only event, designed to allow you to keep external data in synch with the state of the Revit database. To update the Revit database in response to changes in elements, use the [Dynamic Model Update](../../Advanced_Topics/Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Dynamic_Model_Update_html.html) framework.
|
||||
|
||||
**Parent page:** [Transactions](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_html.html)
|
||||
@@ -0,0 +1,32 @@
|
||||
# Transactions
|
||||
|
||||
# Transactions
|
||||
|
||||
Transactions are context-like objects that encapsulate any changes to a Revit model. Any change to a document can only be made while there is an active transaction open for that document. Attempting to change the document outside of a transaction will throw an exception. Changes do not become a part of the model until the active transaction is committed. Consequently, all changes made in a transaction can be rolled back either explicitly or implicitly (by the destructor). Only one transaction per document can be open at any given time. A transaction may consist of one or more operations.
|
||||
|
||||
There are three main classes in the Revit API related to transactions:
|
||||
|
||||
* Transaction
|
||||
|
||||
* SubTransaction
|
||||
|
||||
* TransactionGroup
|
||||
|
||||
|
||||
|
||||
|
||||
This section will discuss each of these classes in more depth. Only the Transaction class is required to make changes to a document. The other classes can be used to better organize changes.
|
||||
|
||||
Note: An exception will be thrown if a transaction is started from an outside thread or outside modeless dialog. Transactions can only be started from supported API workflows, such as part of an external command, event, updater, or call-back.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Transaction Classes](Transactions/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_Transaction_Classes_html.html)
|
||||
* [Transactions in Events](Transactions/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_Transactions_in_Events_html.html)
|
||||
* [Failure Handling Options](Transactions/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_Failure_Handling_Options_html.html)
|
||||
* [Getting Element Geometry and AnalyticalElement](Transactions/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_Getting_Element_Geometry_and_AnalyticalModel_html.html)
|
||||
* [Temporary transactions](Transactions/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Transactions_Temporary_transactions_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
@@ -0,0 +1,151 @@
|
||||
# About views
|
||||
|
||||
# About views
|
||||
|
||||
The Revit API provides access to View properties and the ability to create and delete views programmatically.
|
||||
|
||||
This section is a high-level overview that includes the following:
|
||||
|
||||
* How views are generated
|
||||
* View types
|
||||
* View navigation tools
|
||||
* Creating and deleting views
|
||||
|
||||
### View process
|
||||
|
||||
|
||||
|
||||
|
||||
The following figure illustrates how a view is generated.
|
||||
|
||||
**Figure 94: Create view process**
|
||||
|
||||
Each view is generated by projecting a three-dimensional object onto a two-dimensional projection plane. Projections are divided into two basic classes:
|
||||
|
||||
* Perspective
|
||||
* Parallel
|
||||
|
||||
|
||||
|
||||
After the projection type is determined, you must specify the conditions under which the 3D model is needed and the scene is to be rendered. For more information about projection, refer to the [View3D](./View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_View3D_html.html) section.
|
||||
|
||||
World coordinates include the following:
|
||||
|
||||
* The viewer's eye position
|
||||
* The viewing plane location where the projection is displayed
|
||||
|
||||
|
||||
|
||||
Revit uses two coordinate systems:
|
||||
|
||||
* The global or model space coordinates where the building exists
|
||||
* The viewing coordinate system
|
||||
|
||||
|
||||
|
||||
The viewing coordinate system represents how the model is presented in the observer's view. Its origin is the viewer's eye position whose coordinates in the model space are retrieved by the View.Origin property. The X, Y, and Z axes are represented by the View.RightDirection, View.UpDirection, and View.ViewDirection properties respectively.
|
||||
|
||||
* View.RightDirection is towards the right side of the screen.
|
||||
* View.UpDirection towards the up side of the screen.
|
||||
* View.ViewDirection from the screen to the viewer.
|
||||
|
||||
|
||||
|
||||
The viewing coordinate system is right-handed. For more information, see the [View3D](./View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_View3D_html.html) and the Parallel Projection picture in [View3D](./View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_View3D_html.html).
|
||||
|
||||
Some portions of a 3D model space that do not display, such as those that are behind the viewer or are too far away to display clearly, are excluded before being projected onto the projection plane. This action requires cropping the view. The following rules apply to cropping:
|
||||
|
||||
* Elements outside of the crop region are no longer in the view.
|
||||
|
||||
* The View.GetCropRegionShapeManager method returns a ViewCropRegionShapeManager which provides the boundary information for the crop region, which may or may not be rectangular.
|
||||
|
||||
* The View.CropBoxVisible property determines whether the crop box is visible in the view.
|
||||
|
||||
* The View.CropBoxActive property determines whether the crop box is actually being used to crop the view.
|
||||
|
||||
|
||||
|
||||
|
||||
After cropping, the model is projected onto the projection plane. The following rules apply to the projection:
|
||||
|
||||
* The projection contents are mapped to the screen view port for display.
|
||||
* During the mapping process, the projection contents are scaled so that they are shown properly on the screen.
|
||||
* The View.Scale property is the ratio of the actual model size to the view size.
|
||||
* The view boundary on paper is the crop region, which is a projection of the crop shape on the projection plane.
|
||||
* The size and position of the crop region is determined by the View.OutLine property.
|
||||
|
||||
|
||||
|
||||
You can transform between model space and a view's projection space witht the following methods:
|
||||
|
||||
* TransformWithBoundary.GetModelToProjectionTransform()
|
||||
* TransformWithBoundary.GetBoundary() - Returns the boundary for the model space to view projection space transform.
|
||||
* View.GetModelToProjectionTransforms() - Gets the transforms from the model space to the view projection space. Views with split crop regions. have more than one transform.
|
||||
* View.HasViewTransforms() - Returns true if the view reports model space to view projection space transforms. Schedules and legends, for example, do not report any.
|
||||
|
||||
|
||||
|
||||
Transforming between a view's projection space and sheet space can be done with `Viewport.GetProjectionToSheetTransform()`.
|
||||
|
||||
### View navigation tools
|
||||
|
||||
You may access information about the home view camera currently set in the view cube settings. There may only be one home view camera set for the document. This corresponds to the view orientation and other camera parameters saved when the user invokes the ViewCube UI command to "Set current view as home" in the ViewCube right-click context menu.
|
||||
|
||||
Access the ViewNavigationToolSettings by calling the static method ViewNavigationToolSettings.GetViewNavigationToolSettings() which will return the ViewNavigationToolSettings element associated with the document.
|
||||
|
||||
The ViewNavigationToolSettings will allow you to query whether a home view has been set with the method IsHomeCameraSet() which returns a boolean indicating the current state of the home view setting.
|
||||
|
||||
Access read-only information about the home camera set in the ViewCube by getting a copy of the home camera with the ViewNavigationToolSettings.GetHomeCamera() method. This function returns Null if the home camera is not yet set. The HomeCamera class provides informationabout the camera and view for the Home view orientation stored in the model such as EyePosition and UpDirection.
|
||||
|
||||
### Creating and deleting views
|
||||
|
||||
The Revit Platform API provides numerous methods to create the corresponding view elements derived from Autodesk.Revit.DB.View class. Most view types are created using static methods of the derived view classes. If a view is created successfully, these methods return a reference to the view, otherwise they return null. The methods are described in the following sections specific to each view class.
|
||||
|
||||
Views can also be created using the View.Duplicate() method. A new view can be created from an existing view with options for the new view to be dependent or to have detailing. The following example demonstrates how to create a new dependent view.
|
||||
|
||||
**Code Region: Create a dependent view**
|
||||
---
|
||||
|
||||
|
||||
public View CreateDependentCopy(View view)
|
||||
{
|
||||
View dependentView = null;
|
||||
ElementId newViewId = ElementId.InvalidElementId;
|
||||
if (view.CanViewBeDuplicated(ViewDuplicateOption.AsDependent))
|
||||
{
|
||||
newViewId = view.Duplicate(ViewDuplicateOption.AsDependent);
|
||||
dependentView = view.Document.GetElement(newViewId) as View;
|
||||
if (null != dependentView)
|
||||
{
|
||||
if (dependentView.GetPrimaryViewId() == view.Id)
|
||||
{
|
||||
TaskDialog.Show("Dependent View", "Dependent view created successfully!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dependentView;
|
||||
}
|
||||
|
||||
Delete a view by using the Document.Delete() method with the view Id. You can also delete elements associated with a view. For example, deleting the level element causes Revit to delete the corresponding plan view or deleting the camera element causes Revit to delete the corresponding 3D view.
|
||||
|
||||
### Dependent Views
|
||||
|
||||
As seen above, dependent views can be created using the View.Duplicate() method and passing in the AsDependent value for the ViewDuplicationOption enumerator. A dependent view will remain synchronous with the primary view and all other dependent views , so that when view-specific changes (such as view scale and annotations) are made in one view, they are reflected in all views. Not all view types can be duplicated and you cannot create a dependent view from another dependent view. Use View.CanViewBeDuplicated() to make sure a dependent view can be generated from the view. This method takes a ViewDuplicationOption enum to check whether a view can be duplicated in a specific way. You may be able to duplicate a view as an independent view, but not a dependent view.
|
||||
|
||||
Dependent views have a valid primary view element Id that can be obtained from the method View.GetPrimaryViewId(). Independent views have InvalidElementId as their primary view Id. A dependent view can be converted to an independent view using the View.ConvertToIndependent() method. This method will thrown an exception if the view is not dependent.
|
||||
|
||||
**Code Region: Make a dependent view independent**
|
||||
---
|
||||
|
||||
|
||||
public void MakeViewIndependent(View view)
|
||||
{
|
||||
// Independent views will have an InvalidElementId for the Primary View Id
|
||||
if (view.GetPrimaryViewId() != ElementId.InvalidElementId)
|
||||
{
|
||||
view.ConvertToIndependent();
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,108 @@
|
||||
# Displaced Views
|
||||
|
||||
# Displaced Views
|
||||
|
||||
Create a displaced view using the DisplacementElement class. DisplacementElement is a view-specific element that can be used to cause elements to appear displaced from their actual location. Displaced views are useful to illustrate the relationship model elements have to the model as a whole. The DisplacementElement does not actually change the location of any model elements; it merely causes them to be displayed in a different location.
|
||||
|
||||
For a detailed example of creating displaced views, see the DisplacementElementAnimation sample in the Revit SDK.
|
||||
|
||||
### Creating a Displaced View
|
||||
|
||||
The static DisplacementElement.Create() method c reates a new DisplacementElement. The new DisplacementElement may be a child of a parent DisplacementElement if the parentDisplacementElement parameter is not null. If a parent is specified, the child DisplacementElement's transform will be concatenated with that of the parent, and the displacement of its associated elements will be relative to the parent DisplacementElement.
|
||||
|
||||
The Create() method also requires a document, a list of elements to be displaced, the owner view, and t he translation to be applied to the graphics of the displaced elements. An element may only be displaced by a single DisplacementElement in any view. Assigning an element to more than one DisplacementElement will result in an exception.
|
||||
|
||||
Other static methods of DisplacementElement can be used prior to calling Create() to help prevent any exceptions. CanCategoryBeDisplaced() tests whether elements belonging to a specific category can be displaced, while the overloaded static method CanElementsBeDisplaced() indicates if specific elements may be assigned to a new DisplacementElement. IsAllowedAsDisplacedElement() tests a single element for eligibility to be displaced.
|
||||
|
||||
The static GetAdditionalElementsToDisplace() method will return any additional elements that should be displaced along with the specified element in a specified view. For example, when a wall is displaced, any inserts or hosted elements should also be displaced.
|
||||
|
||||
When creating a child DisplacementElement, the static IsValidAsParentInView() can be used to verify a specific DisplacementElement may be used as a parent in a specific View.
|
||||
|
||||
Other static methods of DisplacementElement can be used to find the DisplacementElement that includes a specific element, to get a list of all displaced elements in a View, or to get all the DisplacementElements owned by a specified View.
|
||||
|
||||
### Working with Displaced Elements
|
||||
|
||||
Once a new DisplacementElement has been created, methods are available to obtain any child DisplacementElements, to get the ids of all elements affected by the DisplacementElement, or to obtain the ids of all elements affected by the DisplacementElement as well as any child DisplacementElements. The ParentId property will return the element id of the parent DisplacementElement, if there is one.
|
||||
|
||||
After creation, the set of elements affected by the DisplacementElement can be modified using SetDisplacedElementIds() or RemoveDisplacedElement(). Additionally, the relative displacement can be changed.
|
||||
|
||||
The method ResetDisplacedElements() will set the translation of the DisplacementElement to (0, 0, 0). The DisplacementElement continues to exist, but its elements are displayed in their actual location.
|
||||
|
||||
### Creating a Displaced Path
|
||||
|
||||
DisplacementPath is a view-specific annotation related to a DisplacementElement. The DisplacementPath class creates an annotation that depicts the movement of the element from its actual location to its displaced location. The DisplacementPath is anchored to the DisplacementElement by a reference to a point on an edge of a displaced element of the DisplacementElement. It is represented by a single line, or a series of jogged lines, originating at the specified point on the displaced element.
|
||||
|
||||
The static DisplacementPath.Create() method requires a document, id of the associated DisplacementElement, a reference that refers to an edge or curve of one of the elements displaced by the DisplacementElement, and a value in the range [0,1] that is a parameter along the edge specified. Once created, the path style of the DisplacementPath can get set using the PathStyle property. The anchor point can also be changed using SetAnchorPoint().
|
||||
|
||||
The following example creates a new displacement by moving the first wall found vertically and horizontally and then adds a displacement path for it.
|
||||
|
||||
**Code Region: Create displacement and path**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateDisplacementAndPath(Document doc, View view)
|
||||
{
|
||||
// Find roof
|
||||
FilteredElementCollector fec = new FilteredElementCollector(doc);
|
||||
fec.OfClass(typeof(RoofBase));
|
||||
RoofBase roof = fec.FirstElement() as RoofBase;
|
||||
|
||||
// Get a geometric reference for the path
|
||||
Reference edgeRef = GetHorizontalEdgeReference(roof);
|
||||
|
||||
using (Transaction t = new Transaction(doc, "CreateDisplacementAndPath"))
|
||||
{
|
||||
t.Start();
|
||||
// Create a new top level DisplacementElement
|
||||
DisplacementElement dispElem = DisplacementElement.Create(doc, new ElementId[] { roof.Id }, new XYZ(10, 0, 20), view, null);
|
||||
|
||||
// Create the path associated to the element
|
||||
DisplacementPath.Create(doc, dispElem, edgeRef, 0.5);
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
private static Reference GetHorizontalEdgeReference(Element elem)
|
||||
{
|
||||
//Find target edge from lower face of roof
|
||||
Options options = new Options();
|
||||
options.ComputeReferences = true;
|
||||
|
||||
GeometryElement geomElem = elem.get_Geometry(options);
|
||||
|
||||
foreach (var geomObj in geomElem)
|
||||
{
|
||||
if (geomObj is Solid)
|
||||
{
|
||||
Solid solid = geomObj as Solid;
|
||||
var faces = solid.Faces;
|
||||
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
BoundingBoxUV box = face.GetBoundingBox();
|
||||
UV midpoint = (box.Min + box.Max) / 2.0;
|
||||
if (face.ComputeNormal(midpoint).Normalize().Z < -0.1) // Downward facing, this is good enough
|
||||
{
|
||||
var edgeLoops = face.EdgeLoops;
|
||||
foreach (EdgeArray edgeArray in edgeLoops)
|
||||
{
|
||||
foreach (Edge edge in edgeArray)
|
||||
{
|
||||
// horizontal?
|
||||
if (Math.Abs(edge.AsCurve().ComputeDerivatives(0.0, true).BasisX.DotProduct(XYZ.BasisZ)) - 1 <= 0.00001)
|
||||
{
|
||||
return edge.Reference;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
The associated DisplacementElement may have a parent DisplacementElement and this parent may have its own parent DisplacementElement, producing a series of ancestors. The terminal point may be the point's original (un-displaced) location, or the corresponding point on any of the intermediate displaced locations corresponding to these ancestor DisplacementElements. The DisplacementPath . AncestorIdx property specifies the end point of the path.
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,479 @@
|
||||
# Displaying Graphics with DirectContext3D
|
||||
|
||||
# Displaying Graphics with DirectContext3D
|
||||
|
||||
## Overview
|
||||
|
||||
DirectContext3D is an API for displaying graphics in Revit by utilizing an internal graphics pipeline that accepts primitives, such as points, lines, and triangles, as input. The external graphics served by DirectContext3D applications exist separately from the host Revit document and do not need to be converted to an internal format. Using DirectContext3D to draw graphics allows external applications to avoid the performance cost associated with permanently importing content into Revit and allows the applications to have more flexibility with managing the external content. However, the applications are responsible for any optimizations that may be necessary. Revit's Coordination Model functionality uses DirectContext3D to display complex graphics served by a Navisworks component that performs sophisticated optimization of the graphics.
|
||||
|
||||
### When to Use DirectContext3D
|
||||
|
||||
The main strengths of DirectContext3D are:
|
||||
|
||||
1. Flexibility gained from not having to import graphics as a prerequisite for drawing.
|
||||
2. Simplicity gained from interaction with an internal graphics pipeline that handles many tasks related to drawing.
|
||||
|
||||
|
||||
|
||||
Due to the flexible nature of the framework, many different applications of DirectContext3D are possible. However, the following scenarios fit the design of the API especially well:
|
||||
|
||||
* Drawing temporary graphics
|
||||
* Visualization of data
|
||||
* Drawing graphics that are served by an external provider
|
||||
|
||||
|
||||
|
||||
### Getting Started with DirectContext3D
|
||||
|
||||
There are three main steps to getting started with DirectContext3D:
|
||||
|
||||
1. Understand how to implement a basic external application using the Revit API.
|
||||
2. Understand how DirectContext3D connects to Revit’s graphics pipeline using callbacks and the tasks that are the responsibility of an external application that utilizes DirectContext3D.
|
||||
3. Learn about the various parts of the API and their purpose.
|
||||
|
||||
|
||||
|
||||
## DirectContext3D Callbacks
|
||||
|
||||
External applications that use DirectContext3D can carry out drawing operations from callbacks that are made by Revit to the applications. The callbacks structure the use of DirectContext3D in such a way that the applications participate in appropriate stages of Revit’s internal drawing process. This constraint makes it possible for geometry submitted by external applications to be drawn in the same way as geometry native to Revit. Support for the callback architecture is provided by a part of Revit API called the External Service Framework (ESF).
|
||||
|
||||
### Drawing as Delegated Functionality
|
||||
|
||||
ESF is a framework that allows Revit to delegate functionality to external applications based on a system of services and servers. In this context, servers are local providers of data or other functionality that constitutes a service. When Revit requests the service to be performed, ESF calls the servers that implement the functionality corresponding to the service. External applications create and register servers for a particular service.
|
||||
|
||||
DirectContext3D contains an external service called DirectContext3DService that interacts with servers implementing the IDirectContext3DServer interface. The functionality delegated to the servers consists of two main tasks:
|
||||
|
||||
1. Drawing external graphics by making DirectContext3D calls.
|
||||
2. Computing the bounding box of the external graphics.
|
||||
|
||||
|
||||
|
||||
The server interface contains two callbacks corresponding to these two tasks: RenderScene() and GetBoundingBox(). Figure 1 summarizes the relationship between DirectContext3D callbacks and ESF.
|
||||
|
||||
**Figure 1: The relationship between DirectContext3D callbacks and ESF.**
|
||||
|
||||
DirectContext3DService is a MultiServerService, which means that it can have multiple servers that are active simultaneously. There is no restriction on the number of external applications and how many DirectContext3D servers each of them registers. Each active server is called back by Revit to participate in the drawing process.
|
||||
|
||||
### Implementing RenderScene()
|
||||
|
||||
For drawing graphics, the most important callback is RenderScene(). To implement this callback, external applications use the main part of the DirectContext3D API to execute drawing operations. The drawing process is discussed in detail in the following sections.
|
||||
|
||||
The graphics drawn by an external application may depend on the current state of Revit, for example the view where drawing is taking place and the display style of the view. For this reason, it is essential that an external application is able to call DirectContext3D (and other Revit API) from within the DirectContext3D callbacks, completing a bi-directional channel of communication with Revit. In particular, one of the roles of the DrawContext object of DirectContext3D is to provide rendering-related information to an application, which is executing inside RenderScene(). Figure 2 illustrates the main tasks of RenderScene() and the role of DrawContext.
|
||||
|
||||
**Figure 2: Communication with Revit from inside RenderScene() callback.**
|
||||
|
||||
## DirectContext3D and Graphics Pipeline in Revit
|
||||
|
||||
DirectContext3D is a graphics API that exposes a low-level part of the graphics pipeline used in Revit internally. To draw graphics using this pipeline external applications submit lists of graphics primitives encoded in pairs of vertex and index buffers. The callbacks of DirectContext3D constrain any interaction with the pipeline to be in lockstep with internal rendering.
|
||||
|
||||
### Relevant Computer Graphics Concepts
|
||||
|
||||
This section provides some computer graphics background concerning the key aspects of the rendering pipeline that external applications can access using DirectContext3D.
|
||||
|
||||
#### Overview of the Drawing Process
|
||||
|
||||
To support rendering of diverse 3D scenes, a graphics API and the drawing process that it represents must be general-purpose. For this reason, graphics packages share a lot of similarities and it is possible to identify certain typical elements of an abstract drawing process in a given API. DirectContext3D belongs to a class of APIs that produce graphics on the screen from geometric primitives, such as triangles, that are specified in terms of the positions of their vertices. These geometric shapes are converted into corresponding pixel-based representations in a process called rasterization. The output of rasterization is stored in 2D buffers, which are similar to bitmap images, and is later presented on the screen.
|
||||
|
||||
There can be many parameters that determine the outcome of the drawing process. The simplest parameters are the positions and colors of the primitive shapes. However, graphics APIs typically implement many drawing operations that can be enabled optionally and whose parameters can be controlled. For example, the rasterized shapes can be blended into the output buffer according to their transparency, instead of overwriting the destination values. There can also be additional drawing operations that are concerned with manipulating the output buffers, rather than the initial geometric shapes. Some drawing operations can be programmable, i.e., specified using a standalone program that is executed at the time of drawing.
|
||||
|
||||
The complexity of a graphics API can be managed by organizing the supported drawing operations into a graphics pipeline, in which each stage can be controlled independently. Optional stages, such as blending for transparent objects, can be enabled only when appropriate objects are submitted into the pipeline for drawing. The act of drawing an object in the output buffer can be considered to begin with setting of the parameters that control the state of the entire pipeline. Although it may be possible for certain state to persist from previous drawing operations, it is important to understand that a given object will be drawn in the intended way only if the total state of the pipeline is correct.
|
||||
|
||||
DirectContext3D is designed along the same lines as many other APIs for drawing graphics to the screen. The API represents a simple pipeline that accepts an encoding of geometric shapes as input and rasterizes them according to the state of the pipeline. However, there is one fundamental difference that complicates the design of DirectContext3D and how it operates: the graphics pipeline is implemented inside of Revit and DirectContext3D is an additional interface level that allows external applications (i.e., Revit plugins) to execute drawing operations using the internal pipeline. The complexity of drawing in Revit necessitates that many pieces of the internal pipeline, for example operations on the output image buffers and the programmable stages, are not exposed through DirectContext3D. On the other hand, these limitations make DirectContext3D simpler to use.
|
||||
|
||||
#### Transformations
|
||||
|
||||
To control the position and orientation of a geometric primitive during drawing, it is necessary to apply a transformation to its vertices. For example, adding a fixed offset to the vertices will translate a shape in a specified direction. Typically, there are several levels of transformations applied to a given object (see Figure 3).
|
||||
|
||||
* **Modeling transformations.** These transformations serve to place a given shape in relationship to others inside the virtual world space. The sizes and positions of shapes in the world space can be given meaning in terms of real world units.
|
||||
* **View transformations.** The virtual scene can be transformed so that it can be presented from a specific viewpoint, which is referred to as an eye or camera. Movements of the camera correspond to transformations applied to the world. For example, moving the camera to the left means that the world moves to the right. (The transformation of the camera is the inverse of the associated transformation of the world.)
|
||||
* **Projection transformations.** To display a 3D scene on a 2D screen requires a projection transformation to be applied. Often two types of projection transformations are implemented: orthographic and perspective.
|
||||
|
||||
|
||||
|
||||
**Figure 3: Transformations and Spaces.**
|
||||
|
||||
DirectContext3D exposes only a single type of transformation, which is referred to as the World transformation (DrawContext.SetWorldTransform()). This transformation is applied to all geometric primitives that are submitted for rendering (before any camera transformations) and should be updated as each object is submitted through the API. The World transformation of DirectContext3D belongs with modeling transformations in the above classification. The rest of the transformations are controlled by Revit. In particular, whether the Revit view is an orthographic or perspective view determines the projection transformation.
|
||||
|
||||
#### Depth Buffer
|
||||
|
||||
To render a 3D scene means to produce a 2D image in which only the visible parts of the objects in the scene are displayed. In a graphics pipeline that is based on rasterization this effect, called hidden surface elimination, is typically achieved using a depth buffer. The depth buffer is an additional 2D image that is produced by the pipeline during rasterization and contains the depth value of each pixel. Comparing depth values during rasterization of each objects allows the pipeline to discard occluded pixels and determine the visible parts of geometry with pixel-level precision.
|
||||
|
||||
The depth buffer hidden surface elimination algorithm can process objects in any order and can correctly update the 2D pixel representation of the scene when additional objects are submitted. DirectContext3D benefits from the depth buffer algorithm by having the algorithm combine rasterized objects drawn by Revit in a given view with the additional objects submitted through the API. The result is a composite image containing objects drawn by Revit and objects drawn by external applications using DirectContext3D.
|
||||
|
||||
### DirectContext3D as an Interface to A Graphics Pipeline
|
||||
|
||||
The main component of DirectContext3D is an interface to a graphics pipeline that accepts an encoding of geometric shapes as input and rasterizes them according to the state of the pipeline (e.g., the world transformation that is set). Compared to a typical graphics API, there are many actions that do not need to be taken or configured using DirectContext3D, because the target of rendering is a Revit view and the work is done inside of Revit. First, it is not necessary to perform any setting up of output image buffers. Second, view navigation in Revit determines most of the transformations that need to be applied to the geometry submitted through DirectContext3D. Third, complex multi-pass rendering operations on submitted geometry and screen-space post-processing effects operating on the output image buffers are performed internally. Similarly, control over advanced materials, shading effects, and texturing is not exposed through DirectContext3D.
|
||||
|
||||
The following sequence of actions lists the basic tasks for which DirectContext3D applications remain to be responsible when using the graphics pipeline:
|
||||
|
||||
1. Encode geometry in a set of vertex and index buffers.
|
||||
2. Set the transformation that the pipeline will use to transform the geometry.
|
||||
3. Control the color and shading of the geometry using an EffectInstance object.
|
||||
4. Submit the geometry into the pipeline.
|
||||
|
||||
|
||||
|
||||
External applications should also be aware of the following provisions of DirectContext3D that are related to submitting graphics into the pipeline:
|
||||
|
||||
* External applications can draw transparent objects by submitting them separately into a dedicated rendering pass.
|
||||
* DirectContext3D provides a callback, GetBoundingBox(), that allows external applications to report the outline of the graphics that they submit. This provision allows Revit views that contain external graphics to be navigated consistently with other Revit views.
|
||||
* Camera parameters and other rendering-related information can be queried with the help of the DrawContext object. This information is useful for an external application that needs to optimize the graphics that it submits into the pipeline.
|
||||
|
||||
|
||||
|
||||
The following subsection provides additional details regarding the geometry encoding, so that the rest of the discussion is grounded with a definition of what constitutes input to the graphics pipeline used with DirectContext3D.
|
||||
|
||||
#### Vertex and Index Buffers
|
||||
|
||||
DirectContext3D supports rendering of three types of primitives: triangles, lines, and points. Each type of primitive is defined in terms of vertices. A geometric object that can be submitted using one drawing operation consists of several primitives of the same type. An object consisting of triangles is referred to as a (triangle) mesh.
|
||||
|
||||
A given vertex in a mesh can be shared among several triangles. The number of vertices submitted for processing can be substantially reduced if a vertex is listed once in a vertex buffer and referenced as many times as required using an index buffer. So, the vertex buffer lists the vertices of an object in any order, while the index buffer contains indices into the vertex buffer. In the case of the triangle primitive, the index buffer contains a set of three indices for each triangle.
|
||||
|
||||
In DirectContext3D a vertex is defined by its position (three floating point values) and one or both of two optional attributes: normal vector (three values) and color (one 32-bit value containing an integer that encodes four color components). Note that the attributes increase the storage requirements for a vertex and increase the benefit of shared vertex reuse due to the index buffer. However, the number of unique vertices may increase for an object if vertices may no longer be shared, because a vertex with the same position has different attribute values in the primitives that are incident on it.
|
||||
|
||||
To give a concrete example, the vertex buffer may look like: 0, 0, 0, 1, 0, 0, 0, 1, 0 (each value is a floating point number). If the vertex format is VertexFormatBits.Position and the primitive is triangle, then each triple of values defines one vertex and there are three vertices. If the vertex format is VertexFormatBits.PositionNormal, there will be an additional set of three values following each position. In other words, the vertex buffer will look like: p0, n0, p1, n1, p2, n2 (p = position, n = normal). The index buffer for one triangle may look like: 0, 1, 2. Each additional triangle requires an additional triple of indices.
|
||||
|
||||
#### Accessing the Graphics Pipeline Using DirectContext3D
|
||||
|
||||
Revit calls external applications twice to contribute their geometry to the graphics pipeline. Execution enters into the external applications when it is time to submit opaque model geometry and the process is repeated a second time for transparent model geometry. A DirectContext3D application submits both opaque and transparent geometry from the RenderScene() callback. The two calls are distinguished by the value of DrawContext.IsTransparentPass(). Other than submitting the transparent geometry no further steps, such as management of blending, need to be taken by the external application. The results of the two rendering passes are composited by Revit internally. Figure 4 illustrates the two rendering passes and the actions that external applications need to take from the RenderScene() callback.
|
||||
|
||||
**Figure 4: Access to the graphics pipeline from RenderScene().**
|
||||
|
||||
External applications can take actions that access the graphics pipeline only when Revit is in the middle of its internal rendering pipeline and calls RenderScene(). The restriction extends to creation of objects such as VertexBuffer that are used in drawing operations. Applications can test that they are executing in the scope that permits access to the graphics pipeline by checking the value of DrawContext.IsAvailable(). DrawContext ties together a lot of the DirectContext3D functionality related to drawing and acts as an interface for collecting certain rendering-related information from Revit, such as the camera parameters. Rendering-related parameters also have meaning only when Revit is in the appropriate state internally, so that execution of calls such as DrawContext.GetCamera() is subject to the constraint represented by IsAvailable().
|
||||
|
||||
Revit also maintains outlines, or bounding boxes, of the geometry contained in a view for the purposes of view navigation and internal optimizations. Therefore, DirectContext3D applications have an additional responsibility to compute the outline of the geometry that they submit. Revit obtains the value using the GetBoundingBox() callback. For performance reasons, it is recommended that external applications cache the value of the outline after computing it (and report the cached value thereafter). Also note that GetBoundingBox() can be called on a different thread than RenderScene(). Figure 5 illustrates the GetBoundingBox() callback.
|
||||
|
||||
**Figure 5: Execution of the GetBoundingBox() callback.**
|
||||
|
||||
## Utilizing DirectContext3D
|
||||
|
||||
DirectContext3D allows an external application to participate in Revit’s internal drawing process by acting as a provider of additional objects for rendering. The format of the external geometry is a list of geometric primitives, such as triangles, encoded in pairs of vertex and index buffers. A server implementing the IDirectContext3DServer interface provides the communication channel, which is necessary for the application to request display-related information from Revit and execute appropriate drawing operations. Revit calls certain methods of the server interface when it is in the correct state for communicating with the external application.
|
||||
|
||||
### Main Steps for Drawing
|
||||
|
||||
Before drawing requests can be issued, an external application must instantiate and register a server derived from IDirectContext3DServer. This can be done as early as inside OnStartup() of IExternalApplication.
|
||||
|
||||
|
||||
ExternalServiceId serviceId = ExternalServices.BuiltInExternalServices.DirectContext3DService;
|
||||
MultiServerService serviceDC3D = ExternalServiceRegistry.GetService(serviceId) as MultiServerService;
|
||||
IDirectContext3DServer testServer = new DC3DTestServer();
|
||||
IList<Guid> activeList = serviceDC3D.GetActiveServerIds();
|
||||
activeList.Add(testServer.GetServerId());
|
||||
serviceDC3D.AddServer(testServer);
|
||||
serviceDC3D.SetActiveServers(activeList);
|
||||
|
||||
The server can begin to interact with Revit’s graphics pipeline as soon as a document is opened and a view is displayed. Without extra work from the application and server, the graphics submitted by the server will be drawn in most types of open Revit views.
|
||||
|
||||
There are two sets of methods that a server implementation must override: those inherited from IExternalServer and those inherited from IDirectContext3DServer. One of the key points is identifying the server via a GUID.
|
||||
|
||||
|
||||
public DC3DTestServer()
|
||||
{
|
||||
serverId = Guid.NewGuid();
|
||||
}
|
||||
virtual public Guid GetServerId() // inherited from IExternalServer
|
||||
{
|
||||
return serverId;
|
||||
}
|
||||
|
||||
The main work performed by the server is inside RenderScene() and GetBoundingBox(). A detailed example is provided further below. A possible sequence of calls inside RenderScene() may look like this in pseudocode:
|
||||
|
||||
|
||||
Use View and DisplayStyle arguments to discover properties of the view.
|
||||
Use DrawContext methods such as GetCamera() to get additional information.
|
||||
If allocating new buffers
|
||||
Calculate buffer sizes and construct: VertexBuffer, IndexBuffer, VertexFormat.
|
||||
Given vertex format, construct a list of vertices for the geometry.
|
||||
Fill vertex and index buffers.
|
||||
While iterating over vertices, update the outline of the geometry.
|
||||
Unmap buffers.
|
||||
If a new EffectInstance is needed, construct it.
|
||||
Call DrawContext.FlushBuffer().
|
||||
|
||||
A server can re-use objects such as VertexBuffer and EffectInstance from one invocation of RenderScene() to another, which is better for performance. However, the objects can become invalid due to a change in low-level graphics state internal to Revit. A DirectContext3D server must check the validity of objects using their IsValid() methods and be prepared to have to re-create them. In a minimal application, the code can be simpler if DirectContext3D objects are not allowed to persist between the calls.
|
||||
|
||||
At the time when a server needs to generate the contents of vertex and index buffers, it is also convenient to compute the outline of the geometry, which is needed for GetBoundingBox(). When the outline is already computed, GetBoundingBox() can simply return it. However, there is a complication: a server should expect that GetBoundingBox() and RenderScene() can be called in any order and on different threads. So, a server should be able to compute the outline of its geometry independently of drawing it. Synchronization may be needed to avoid a race condition when shared state is accessed simultaneously from the two callbacks.
|
||||
|
||||
### DirectContext3D Server Interface Methods
|
||||
|
||||
A DirectContext3D server inherits the following methods from the IExternalServer interface. These methods characterize the server as a component of the External Service Framework (ESF).
|
||||
|
||||
|
||||
Guid GetServerId(): The GUID that identifies the server.
|
||||
String GetVendorId(): The vendor of the server.
|
||||
ExternalServiceId GetServiceId(): See below.
|
||||
String GetName(): The name of the server.
|
||||
String GetDescription(): The description of the server.
|
||||
GetServiceId() should be implemented like this:
|
||||
virtual public ExternalServiceId GetServiceId()
|
||||
{
|
||||
return ExternalServices.BuiltInExternalServices.DirectContext3DService;
|
||||
}
|
||||
|
||||
The second set of interface methods comes from the IDirectContext3DServer interface and contains callbacks that the server should use to submit geometry for drawing.
|
||||
|
||||
bool CanExecute(View view): allows the server to prevent its callbacks (UseInTransparentPass(), GetBoundingBox(), and RenderScene()) from being executed for the specified view.
|
||||
|
||||
bool UseInTransparentPass(View view): allows the server’s RenderScene() to be called an additional time, so that the server can draw transparent geometry.
|
||||
|
||||
Outline GetBoundingBox(View view): allows the server to specify the outline of the geometry that it submits for the view. Note that the view argument can be null, in which case the server is expected to return a view-independent outline. The outline should be transformed in the same way as the corresponding geometry if the server uses DrawContext.SetWorldTransform().
|
||||
|
||||
void RenderScene(View view, DisplayStyle displayStyle): allows the server to submit geometry for rendering.
|
||||
|
||||
String GetApplicationId(): used for internal addins only. The server should return the empty string.
|
||||
|
||||
String GetSourceId(): used for internal addins only. The server should return the empty string.
|
||||
|
||||
bool UsesHandles(): used for internal addins only. The server should return false.
|
||||
|
||||
### DirectContext3D Objects
|
||||
|
||||
**VertexFormatBits.** Numerical representation of the format of a vertex. Vertices always have position and can optionally have a normal vector, a color, or both a normal vector and a color. VertexFormatBits values are: Position, PositionNormal, PositionColored, and PositionNormalColored.
|
||||
|
||||
**VertexFormat.** Specifies the format of vertex data in a vertex buffer. Used when calling FlushBuffer(). Can become invalid in which case the external application must recreate the object.
|
||||
|
||||
**Vertex.** The base class for VertexPosition, VertexPositionNormal, VertexPositionColored, and VertexPositionNormalColored. Each derived class contains the data necessary to represent one vertex of the corresponding format in 3D space. Objects of these classes can be used with DirectContext3D vertex streams to fill vertex buffers.
|
||||
|
||||
**VertexStream.** Has the following subclasses: VertexStreamPosition, VertexStreamPositionNormal, VertexStreamPositionColored, and VertexStreamPositionNormalColored. See below for an explanation of the functionality provided by DirectContext3D vertex streams.
|
||||
|
||||
**VertexBuffer.** A buffer that stores vertex data for rendering. Must be mapped before it can be written to and unmapped before it can be submitted using FlushBuffer(). Can become invalid in which case the external application must recreate the object and its contents.
|
||||
|
||||
**PrimitiveType.** Numerical representation of the type of primitive. PrimitiveType values are: TriangleList, LineList, PointList.
|
||||
|
||||
**IndexPrimitive.** The base class for IndexPoint, IndexLine, and IndexTriangle. Similar to the vertex classes, but each derived class represents one primitive (point, line, or triangle) in the index buffer. Objects of these classes can be used with DirectContext3D index streams to fill index buffers.
|
||||
|
||||
**IndexStream.** Similar to VertexStream. Has subclasses: IndexStreamPoint, IndexStreamLine, and IndexStreamTriangle.
|
||||
|
||||
**IndexBuffer.** Similar to VertexBuffer. Can become invalid.
|
||||
|
||||
**EffectInstance.** Determines the appearance of geometry when it is drawn. Used when FlushBuffer() is called. Can become invalid in which case the external application must recreate the object and its contents.
|
||||
|
||||
**DrawContext.** The central component of the DirectContext3D API, consisting of static methods that can be used to submit geometry for drawing and obtain information about the state of the view where rendering is occurring. DrawContext enforces the constraint that drawing-related operations can occur only when Revit is in the appropriate state internally.
|
||||
|
||||
### Using Streams to Fill Buffers
|
||||
|
||||
The functionality of DirectContext3D streams is an optional feature that is intended to make it easier to get started with using the API. The streams are adapters for VertexBuffer and IndexBuffer objects that insert vertices and indices into the buffers, respectively. When inserting data into the buffers, which are flat arrays, the streams minimize the opportunity for errors by keeping track of the number of data needed for each complete object being written. Additionally, a stream keeps track of the current state of a buffer, such as the current position for writing to the buffer, as well as its capacity and mapped status.
|
||||
|
||||
For example, a VertexBuffer is an array of floats that can contain vertices of one format, such as PositionNormal. To write one vertex of this format into the vertex buffer it is necessary to write six floats. (The size of the vertex can be determined by calling the static function VertexPositionNormal.GetSizeInFloats().) This write operation can be performed by using a stream object as follows:
|
||||
|
||||
1. Obtain an instance of VertexStreamPositionNormal from the VertexBuffer instance.
|
||||
2. Create an object of type VertexPositionNormal, which contains the data corresponding to the vertex.
|
||||
3. Call addVertex() of the VertexStreamPositionNormal stream object, which will only accept an object of type VertexPositionNormal as an argument.
|
||||
4. Repeat steps 2 and 3 for additional vertices.
|
||||
|
||||
|
||||
|
||||
The effect of this process is to write data into the buffer associated with the stream one float at a time. However, static type checking ensures that vertices of the intended format are written. Even more, using streams ensures that vertices are written without overlap and that the correct number of data is written for each vertex.
|
||||
|
||||
The alternative to using streams is to obtain the address of the mapped buffer using GetMappedHandle() and to write data into the memory, while keeping track of the remaining capacity of the buffer. This unstructured way of filling a buffer may be more appropriate than using streams in some situations. For example, the Coordination Model plugin relies on an external library to supply the contents of vertex and index buffers. Providing the library with a memory address for writing the data (as well as the size limit of each buffer) keeps the interface between the plugin and the library simple.
|
||||
|
||||
### Using VertexFormat and EffectInstance
|
||||
|
||||
Solid geometry rendered using DirectContext3D can be shaded in several ways depending on its vertex format and the effect instance employed. As a server prepares geometry for rendering, it must determine the following:
|
||||
|
||||
1. The source of the color that the geometry can use.
|
||||
2. The type of shaded appearance applicable to the geometry.
|
||||
3. The combination of VertexFormat and EffectInstance that will determine the final appearance of the geometry.
|
||||
|
||||
|
||||
|
||||
For the first choice, the color (and transparency) can be specified in the effect instance for a whole piece of geometry submitted in one invocation of FlushBuffer(). Alternatively, the color can be specified for each vertex individually, in which case the color in the interior of each triangle will be linearly interpolated during rasterization. For the latter option to be available, vertex data must include the color attribute, so that the format of the vertices should be either PositionColored or PositionNormalColored.
|
||||
|
||||
For the second choice, there are two possible types of shaded appearance for the geometry, corresponding to either the shaded display style or the consistent colors display style. In the shaded display style, surfaces are lit according to the direction of their normals, while in the consistent colors style surfaces have a flat appearance. For the shaded appearance to be applicable to a piece of geometry, its vertices must provide the normal attribute, so that the vertex format should be either PositionNormal or PositionNormalColored. The different types of shading are illustrated in Figure 6.
|
||||
|
||||
**Figure 6: Different types of shaded appearance.**
|
||||
|
||||
The final appearance of the geometry is determined when it is submitted using FlushBuffer() and a combination of VertexFormat and EffectInstance. VertexFormat must exactly describe the format of the vertex data in the vertex buffer and determines which display options are available for the piece of geometry. A specific display option is selected according to the vertex format setting that has been provided to the constructor of EffectInstance. Therefore, it is possible to store vertex data in a certain format and to draw it with different shading options by flushing the vertex buffer with an appropriate effect instance. For a combination of VertexFormat and EffectInstance to be valid, EffectInstance.MatchesFormat(vertexFormat) must be true. The following table lists the results of different VertexFormat and EffectInstance pairings (P = Position, N = Normal, C = Colored). The last row of the table is also visualized in Figure 7.
|
||||
|
||||
There are two different sets of color-related properties that apply to an effect instance depending on the vertex format provided in the object’s constructor. (However the properties may have no effect if the colors come from the vertices.) The flat shaded appearance has only one color parameter. The lit appearance has the following parameters: ambient color, diffuse color, specular color, and glossiness. In both cases, the transparency value can also be set. Transparency is further discussed in the following section, which also includes an example of setting the other parameters of an effect instance.
|
||||
|
||||
**Figure 7: Using VertexFormat and EffectInstance.**
|
||||
|
||||
There are two minor limitations that reduce the number of options that a server has when selecting a VertexFormat and EffectInstance for its geometry. First, shaded objects can not be correctly displayed in a view whose display style is consistent colors, or hidden line. To avoid this situation a server should check the display style argument to its RenderScene() method and fall back to using an EffectInstance that is set up for a flat appearance. Second, the ambient shadows graphics display option requires that normals are provided even for geometry that should be displayed using flat shading. Therefore, it may be simpler for a server to always limit itself to using the PositionNormal and PositionNormalColored formats only.
|
||||
|
||||
### Using Transparency and Color
|
||||
|
||||
Each time a transparent object is drawn, pixels in the output area covered by the transparent objects are adjusted according to an operation called blending. To perform blending, Revit draws transparent objects in a separate pass after opaque objects. For external applications using DirectContext3D management of these two passes is simplified, so that an external application can draw transparent objects by submitting them in the same way as opaque objects. In other words, drawing transparent objects is equivalent to submitting an additional scene with only transparent objects in it.
|
||||
|
||||
To be able to submit the transparent objects, the external application should have an IDirectContext3DServer that returns true from UseInTransparentPass(View view). The server’s RenderScene() call back will be executed an additional time by Revit. The two calls of RenderScene() for opaque and transparent objects can be distinguished by testing DrawContext.IsTransparentPass().
|
||||
|
||||
The application can control the degree of transparency of an object using its color. In graphics, it is common to specify color using four components: red, green, blue, and alpha. Each color component is an 8-bit unsigned integer ranging in value from 0 to 255. Alpha determines transparency with the value 255 being fully transparent. With the addition of DirectContext3D to Revit API a new color class is provided, ColorWithTransparency, that allows manipulation of all four of its components. The components are stored in a single 32-bit integer in the order ABGR, with A being the highest byte. However, the meaning of the components can be interpreted differently in certain usage scenarios.
|
||||
|
||||
When buffer contents are filled out using DirectContext3D streams the conversion needed by scenario 2 is carried out automatically by DirectContext3D.
|
||||
|
||||
Scenario 3 is the situation when an effect instance is used to specify the color and transparency of geometry submitted in a single invocation of FlushBuffer(). The color-related properties of an effect instance can be updated as shown below. Note that the range of the transparency value is adjusted for the call to SetTransparency().
|
||||
|
||||
|
||||
VertexFormatBits format;
|
||||
ColorWithTransparency color;
|
||||
...
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormatBits.Position:
|
||||
effect.SetColor(color.GetColor());
|
||||
effect.SetTransparency(color.GetTransparency() / 255.0);
|
||||
break;
|
||||
case VertexFormatBits.PositionColored: break;
|
||||
case VertexFormatBits.PositionNormal:
|
||||
effect.SetAmbientColor(color.GetColor());
|
||||
effect.SetDiffuseColor(color.GetColor());
|
||||
effect.SetTransparency(color.GetTransparency() / 255.0);
|
||||
break;
|
||||
case VertexFormatBits.PositionNormalColored: break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
### Example: Drawing a Cube
|
||||
|
||||
The low-level nature of DirectContext3D provides for many options for defining the format and primitives of the geometry that is submitted for drawing. In the following example, a cube is defined as a mesh containing 12 triangles (6 faces with 2 triangles each). Additionally, the vertices of the cube are paired with normal vectors corresponding to the faces. Thus 8 vertices of the geometric cube appear in 3 faces each and have a different normal in each face. So, the total number of distinct vertices in the mesh is 24.
|
||||
|
||||
|
||||
using Autodesk.Revit.DB.DirectContext3D;
|
||||
public const int NumVertices = 24; // 8 vertices with 3 choices of normal vector
|
||||
public const PrimitiveType Primitive = PrimitiveType.TriangleList;
|
||||
public const int NumPrimitives = 12; // 6 faces, 2 triangles each
|
||||
|
||||
The vertex and normal data can be stored in arrays for convenience:
|
||||
|
||||
|
||||
XYZ[] vertexNormals = new XYZ[]
|
||||
{
|
||||
new XYZ(0.0, 0.0, 1.0), //+Z normal
|
||||
// . . . 6 entries total
|
||||
};
|
||||
XYZ[] vertexPositions = new XYZ[NumVertices]
|
||||
{
|
||||
new XYZ( // . . .
|
||||
// . . . 24 entries total
|
||||
};
|
||||
|
||||
The next step is to create and map a vertex buffer and an index buffer. The arithmetic for computing the capacity of the buffers is structured using some helper functions.
|
||||
|
||||
|
||||
public static int GetPrimitiveSize(PrimitiveType primitive)
|
||||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case PrimitiveType.LineList: return IndexLine.GetSizeInShortInts();
|
||||
case PrimitiveType.PointList: return IndexPoint.GetSizeInShortInts();
|
||||
case PrimitiveType.TriangleList: return IndexTriangle.GetSizeInShortInts();
|
||||
default: break;
|
||||
}
|
||||
return IndexTriangle.GetSizeInShortInts();
|
||||
}
|
||||
Page 21
|
||||
public static int GetVertexSize(VertexFormatBits format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormatBits.Position: return VertexPosition.GetSizeInFloats();
|
||||
case VertexFormatBits.PositionColored: return VertexPositionColored.GetSizeInFloats();
|
||||
case VertexFormatBits.PositionNormal: return VertexPositionNormal.GetSizeInFloats();
|
||||
case VertexFormatBits.PositionNormalColored: return VertexPositionNormalColored.GetSizeInFloats();
|
||||
default: break;
|
||||
}
|
||||
return VertexPosition.GetSizeInFloats();
|
||||
}
|
||||
// . . .
|
||||
int NumIndices = GetPrimitiveSize(Primitive) * NumPrimitives;
|
||||
VertexBuffer vertexBuffer = new VertexBuffer( GetVertexSize( VertexFormatBits.PositionNormal) * NumVertices);
|
||||
IndexBuffer indexBuffer = new IndexBuffer(NumIndices);
|
||||
vertexBuffer.Map(GetVertexSize(VertexFormatBits.PositionNormal) * NumVertices);
|
||||
indexBuffer.Map(NumIndices);
|
||||
|
||||
Next the pair of buffers can be filled using vertex and index streams. Although only the PositionNormal format is used in this example, the following code is set up to handle the other formats. The handling of streams associated with different formats is only a suggestion that shows how to avoid type casting, which can clutter the code in a larger application that uses multiple formats.
|
||||
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormatBits.Position: VertexStreamP = vertexBuffer.GetVertexStreamPosition(); break;
|
||||
case VertexFormatBits.PositionColored: VertexStreamPC = vertexBuffer.GetVertexStreamPositionColored(); break;
|
||||
case VertexFormatBits.PositionNormal: VertexStreamPN = vertexBuffer.GetVertexStreamPositionNormal(); break;
|
||||
case VertexFormatBits.PositionNormalColored: VertexStreamPNC = vertexBuffer.GetVertexStreamPositionNormalColored(); break;
|
||||
default: break;
|
||||
}
|
||||
switch (primitive)
|
||||
{
|
||||
case PrimitiveType.LineList: IndexStreamL = indexBuffer.GetIndexStreamLine(); break;
|
||||
case PrimitiveType.PointList: IndexStreamP = indexBuffer.GetIndexStreamPoint(); break;
|
||||
case PrimitiveType.TriangleList: IndexStreamT = indexBuffer.GetIndexStreamTriangle(); break;
|
||||
default: break;
|
||||
}
|
||||
// . . .
|
||||
for (int vertex = 0; vertex < NumVertices; ++vertex)
|
||||
{
|
||||
XYZ vertexPosition = vertexPositions[vertex];
|
||||
XYZ vertexNormal = vertexNormals[vertex / 4];
|
||||
VertexStreamPN.AddVertex(new VertexPositionNormal(vertexPosition, vertexNormal));
|
||||
}
|
||||
// Stitch the vertices in the vertex buffer into triangles.
|
||||
for (int indexSet = 0; indexSet < 3; ++indexSet)
|
||||
{
|
||||
int indexBase = 8 * indexSet;
|
||||
IndexStreamT.AddTriangle(new IndexTriangle(0 + indexBase, 2 + indexBase, 3 + indexBase));
|
||||
IndexStreamT.AddTriangle(new IndexTriangle(0 + indexBase, 3 + indexBase, 1 + indexBase));
|
||||
indexBase += 4;
|
||||
IndexStreamT.AddTriangle(new IndexTriangle(0 + indexBase, 3 + indexBase, 2 + indexBase));
|
||||
IndexStreamT.AddTriangle(new IndexTriangle(0 + indexBase, 1 + indexBase, 3 + indexBase));
|
||||
}
|
||||
|
||||
When the buffers are unmapped they are ready to be submitted for drawing. However, FlushBuffer() needs one additional piece of information, which is the EffectInstance.
|
||||
|
||||
|
||||
vertexBuffer.Unmap();
|
||||
indexBuffer.Unmap();
|
||||
EffectInstance effect = DC3DGraphics.GetEffectInstance(VertexFormatBits.PositionNormal);
|
||||
ColorWithTransparency color = new ColorWithTransparency(0, 0, 100, 0);
|
||||
effect.SetAmbientColor(color.GetColor());
|
||||
effect.SetDiffuseColor(color.GetColor());
|
||||
|
||||
The final step is to call FlushBuffer().
|
||||
|
||||
|
||||
Management of DirectContext3D objects can depend on the application. For example, an application that expects to support all of the vertex formats can allocate a VertexFormat of each type and use the four objects in a centralized manner.
|
||||
|
||||
A DirectContext3D server also needs to compute the outline of the geometry that it submits. In the case of a cube, the outline can be determined from knowing that the geometry is a cube of a pre-determined size. More generally, the outline of a triangle mesh can be determined by adding each vertex of the mesh to a growing outline. Note that if SetWorldTransform() is used, the server must return the transformed outline from GetBoundingBox().
|
||||
|
||||
## Current Features and Limitations
|
||||
|
||||
Revit and DirectContext3D share a fundamental connection in terms of the graphics pipeline that makes it possible for DirectContext3D graphics to be combined with graphics generated internally by Revit. This relationship allows many of the display-related features of Revit to work seamlessly with DirectContext3D graphics. However, DirectContext3D is limited to a subset of Revit’s functionality and there are features of Revit that would be too costly in terms of performance to be used with DirectContext3D. Additionally, some features of Revit that are fundamentally compatible with DirectContext3D are not currently exposed through the API, because the features require a lot of configuration and management of external sources of data (e.g., textures).
|
||||
|
||||
### DirectContext3D-compatible Display Features of Revit
|
||||
|
||||
**Composition of graphics in the same view.** DirectContext3D and Revit graphics are composited using the same depth buffer. This allows DirectContext3D and Revit graphics to occlude each other correctly.
|
||||
|
||||
**Anti-aliasing.** Anti-aliasing improves the visual quality of boundaries between areas of different color resulting from rasterization of primitives such as lines and polygons. Visual artifacts occur, because rasterization determines the location of boundaries with pixel-level precision. DirectContext3D and Revit graphics use the same anti-aliasing scheme to mitigate the artifacts.
|
||||
|
||||
**Transparency.** DirectContext3D applications can draw transparent objects by submitting them into the transparent rendering pass of Revit.
|
||||
|
||||
**Orthographic and perspective views.** Graphics submitted using DirectContext3D are transformed using orthographic or perspective projection according to the setting of each view.
|
||||
|
||||
**Discipline-specific views.** DirectContext3D graphics are drawn in Architecture, MEP, and Structural views.
|
||||
|
||||
**Section box.** Revit’s section box functionality clips away parts of the model. The clipping applies to DirectContext3D graphics in the same way as to graphics generated by Revit.
|
||||
|
||||
**Image export.** Graphics currently displayed in a Revit view, including DirectContext3D graphics, can be exported as an image with a specified format and resolution.
|
||||
|
||||
**Ambient shadows.** Ambient shadows effect is a screen-space post-processing pass that simulates variations in shading that result from nearby objects blocking the light. When the effect is activated for a Revit view, both Revit and DirectContext3D graphics are processed. For the effect to work correctly for DirectContext3D graphics, the submitted geometry must include the normal vector attribute.
|
||||
|
||||
**Depth Cueing.** Depth Cueing is a post-processing effect, which helps to visualize the depth of objects in a view by making objects that are farther away appear as if they are receding into a fog. Graphics submitted using DirectContext3D are subject to this effect in the same way as graphics generated by Revit.
|
||||
|
||||
**Progressive Drawing.** Revit draws graphics incrementally by dividing drawing operations into batches. After each batch is processed, Revit checks whether the remaining batches do not need to be finished, because graphics need to be redrawn again due to UI events. The ability to interrupt drawing early allows Revit to be more responsive to user input. When DirectContext3D applications provide graphics to Revit, they can call DrawContext.IsInterrupted() to find out whether they are wasting time on drawing operations that do not need to be completed.
|
||||
|
||||
### Limitations of DirectContext3D
|
||||
|
||||
**Printing only as a raster image.** DirectContext3D is based on the part of Revit’s graphics pipeline that is used for rendering graphics to the screen via rasterization. Therefore, having DirectContext3D graphics in a view forces that view to be printed in a raster format.
|
||||
|
||||
**No advanced materials.** Graphics displayed in Revit’s views can use advanced shading effects and textures. However, DirectContext3D does not provide a way to manage and communicate the necessary information (such as a shader program or a texture) to Revit’s graphics pipeline.
|
||||
|
||||
**No shadows.** Revit does not process DirectContext3D graphics in a way that allows the graphics to cast shadows.
|
||||
|
||||
**2D graphics and annotations.** DirectContext3D provides no special support for 2D drawing operations and graphics primitives defined in a 2D space (i.e., all DirectContext3D vertices have three components). Additionally, some 2D graphics in Revit have special meaning as annotations and DirectContext3D does not provide a way to draw such objects. All graphics drawn using DirectContext3D are classified as model objects.
|
||||
|
||||
**Selection and snapping.** DirectContext3D does not provide support for picking and does not provide a way for external applications to use any internal capabilities of Revit related to selection and snapping.
|
||||
|
||||
**Saving of DirectContext3D graphics with the document.** The state of DirectContext3D graphics that are displayed in a view depends on the external applications that are repeatedly requested to resubmit the graphics for drawing. Permanent storage of any necessary state is left as a responsibility of each individual application.
|
||||
|
||||
**Animation.** DirectContext3D is primarily designed for drawing static scenes.
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,203 @@
|
||||
# Revisions
|
||||
|
||||
# Revisions
|
||||
|
||||
The Revit API provides several classes and members for accessing project Revisions, their settings and associated Revision Clouds.
|
||||
|
||||
## Settings
|
||||
|
||||
The RevisionSettings class allows an application to read and modify the project-wide settings that affect Revisions and Revision Clouds. The static RevisionSettings.GetRevisionSettings() method returns the RevisionSettings object for the given project document. The following properties can be used to access project-wide Revision settings:
|
||||
|
||||
* RevisionCloudSpacing - determines the size in paper space of revision clouds drawn in a project.
|
||||
* RevisionNumbering - determines whether revision numbers for the project are determined on a per sheet or a whole project basis. The AlphanumericRevisionSettings class contains settings that apply to Revisions with the Alphanumeric RevisionNumberType. The RevisionSettings methods GetAlphanumericRevisionSettings() and SetAlphanumericRevisionSettings() provide read and write access to the AlphanumericRevisionSettings.
|
||||
|
||||
|
||||
|
||||
AlphanumericRevisionSettings offers the following members:
|
||||
|
||||
* Prefix - a prefix to be prepended to each revision number with alphanumeric type.
|
||||
* Suffix - a suffix to be appended to each revision number with alphanumeric type.
|
||||
* GetSequence() - gets the list of strings to be used as the numbering sequence for revisions with the alphanumeric type.
|
||||
* SetSequence() - sets the list of strings for numbering revisions of this type. Similarly, the NumericRevisionSettings class contains settings that apply to Revisions with the Numeric RevisionNumberType. The RevisionSettings methods GetNumericRevisionSettings () and SetNumericRevisionSettings() provide read and write access to these settings. NumericRevisionSettings offers the following members:
|
||||
|
||||
|
||||
|
||||
* Prefix - a prefix to be prepended to each revision number with numeric type.
|
||||
|
||||
* Suffix - a suffix to be appended to each revision number with numeric type.
|
||||
|
||||
* StartNumber property - the value to be used as the first number in the sequence of numeric revisions.
|
||||
|
||||
When revision clouds appear on a sheet, the revision number of each revision can be displayed either by tagging the revision cloud or by a revision schedule within the sheet's titleblock. There are two ways the number can be determined:
|
||||
|
||||
* **Per project** : The value of the Revision numbers will always correspond to the project-wide Revision Sequence Number assigned to the revision. For example, if revision clouds for revisions with sequence numbers 5, 7, and 8 are placed on a sheet then revision tags and schedules on that sheet would display 5, 7, and 8.
|
||||
|
||||
* **Per sheet** : Revision numbers will be assigned consecutive numbers based on the revision clouds visible on that sheet. For example, if revision clouds for revisions assigned project-wide Revision Sequence Numbers 5, 7, and 8 are placed on a sheet then revision tags and schedules on that sheet would display 1, 2, and 3. The sequence on the sheet will still follow the relative ordering of the Revision Sequence Numbers, so in this example revision 5 would be displayed as 1 on the sheet, revision 7 would be displayed as 2, etc.
|
||||
|
||||
|
||||
|
||||
|
||||
The Revision class allows an application to read and modify the existing revisions in a project and to create new revisions. The Revision object represents the data related to a single revision in the project. It has properties such IssuedBy, IssuedTo, RevisionNumber, SequenceNumber and RevisionDate. Revision clouds and tags can be associated with a particular Revision object to display its properties on sheets.
|
||||
|
||||
The revisions in the project are stored in a specific order called the revision sequence. The revision sequence represents the conceptual sequence in which revisions will be issued. The static method Revision.GetAllRevisionIds() will return the ids of all Revisions in this order. The static method Revision.ReorderRevisionSequence() can be used to change the sequence of revisions with the project. Note that the newly specified sequence must include every Revision in the project exactly once and that changing the sequence of Revisions can change the SequenceNumber and RevisionNumber of Revisions that have already been issued.
|
||||
|
||||
The `RevisionNumberingSequence` class defines the sequences by which numbers are assigned to Revisions. Revision numbering is either numeric or alphanumeric. Alphanumeric from the API corresponds to the UI concept of "Custom". Members of this class provide the ability to create, read and modify the settings related to Revision numbering sequences.
|
||||
|
||||
`Revision.GetRevisionNumberingSequenceId()` and `Revision.SetRevisionNumberingSequenceId()` provide access to the sequence which controls a revision's numbering.
|
||||
|
||||
The static Create() method will create a new Revision in the specified document. In the sample below, multiple revisions are added and their properties are set.
|
||||
|
||||
Code Region: Creating new revisions
|
||||
---
|
||||
|
||||
|
||||
public IList<Revision> AddRevisions(Document document)
|
||||
{
|
||||
IList<Revision> newRevisions = new List<Revision>();
|
||||
using (Transaction createRevision = new Transaction(document, "createRevision"))
|
||||
{
|
||||
createRevision.Start();
|
||||
newRevisions.Add(AddNewRevision(document, "Include door tags", "manager1", "employee1", 1, DateTime.Now));
|
||||
newRevisions.Add(AddNewRevision(document, "Add a section view", "manager1", "employee1", 2, DateTime.Now));
|
||||
newRevisions.Add(AddNewRevision(document, "Make callout view larger", "manager1", "employee1", 3, DateTime.Now));
|
||||
createRevision.Commit();
|
||||
}
|
||||
|
||||
return newRevisions;
|
||||
}
|
||||
|
||||
private Revision AddNewRevision(Document document, string description, string issuedBy, string issuedTo, int sequenceNumber, DateTime date)
|
||||
{
|
||||
Revision newRevision = Revision.Create(document);
|
||||
newRevision.Description = description;
|
||||
newRevision.IssuedBy = issuedBy;
|
||||
newRevision.IssuedTo = issuedTo;
|
||||
|
||||
AlphanumericRevisionSettings ars = new AlphanumericRevisionSettings();
|
||||
RevisionNumberingSequence sequence = RevisionNumberingSequence.CreateAlphanumericSequence(document, "name", ars);
|
||||
newRevision.RevisionNumberingSequenceId = sequence.Id;
|
||||
|
||||
newRevision.RevisionDate = date.ToShortDateString();
|
||||
return newRevision;
|
||||
}
|
||||
|
||||
Two methods, CombineWithNext() and CombineWithPrevious() allow an application to combine a specified Revision with the next or previous Revision in the model. Combining the Revisions means that the RevisionClouds and revision tags associated with the specified Revision will be reassociated with the next Revision and the specified Revision will be deleted from the model. This method returns the ids of the RevisionClouds that were reassociated. However, these operations can only be implemented if neither Revision has been issued.
|
||||
|
||||
The following example demonstrates use of the CombineWithNext() method. It also uses the GetAllRevisionIds() method to find the next revision to be sure the CombineWithNext() method will be successful.
|
||||
|
||||
Code Region: Combining revisions
|
||||
---
|
||||
|
||||
|
||||
private bool CombineRevision(Document document, Revision revision)
|
||||
{
|
||||
bool combined = false;
|
||||
// Can only combine two revisions if neither have been issued
|
||||
if (revision.Issued == false)
|
||||
{
|
||||
ElementId revisionId = revision.Id;
|
||||
Revision nextRevsion = GetNextRevision(document, revisionId);
|
||||
if (nextRevsion != null && nextRevsion.Issued == false)
|
||||
{
|
||||
ISet<ElementId> revisionCloudIds = Revision.CombineWithNext(document, revisionId);
|
||||
combined = true;
|
||||
int movedClouds = revisionCloudIds.Count;
|
||||
if (movedClouds > 0)
|
||||
{
|
||||
RevisionCloud cloud = document.GetElement(revisionCloudIds.ElementAt(0)) as RevisionCloud;
|
||||
if (cloud != null)
|
||||
{
|
||||
string msg = string.Format("Revision {0} deleted and {1} revision clouds were added to Revsion {2}",
|
||||
revisionId.ToString(), movedClouds, cloud.RevisionId.ToString());
|
||||
TaskDialog.Show("Revision Combined", msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
private Revision GetNextRevision(Document document, ElementId currentRevisionId)
|
||||
{
|
||||
Revision nextRevision = null;
|
||||
IList<ElementId> revisionIds = Revision.GetAllRevisionIds(document);
|
||||
int currentRevisionIndex = -1;
|
||||
for (int n = 0; n < revisionIds.Count; n++)
|
||||
{
|
||||
if (revisionIds[n] == currentRevisionId)
|
||||
{
|
||||
currentRevisionIndex = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the current revision id was found and is not the last index
|
||||
if (currentRevisionIndex >= 0 && currentRevisionIndex < revisionIds.Count - 1)
|
||||
{
|
||||
ElementId nextRevisionId = revisionIds[currentRevisionIndex + 1];
|
||||
nextRevision = document.GetElement(nextRevisionId) as Revision;
|
||||
}
|
||||
|
||||
return nextRevision;
|
||||
}
|
||||
|
||||
## Revision clouds
|
||||
|
||||
A RevisionCloud is a graphical "cloud" that can be displayed on a view or sheet to indicate where revisions in the model have occurred. The RevisionCloud class allows an application to access information about the revision clouds that are present within a model and to create new revision clouds.
|
||||
|
||||
RevisionClouds are view specific and can be created in most graphical views, except 3D.
|
||||
|
||||
Note also that when a RevisionCloud is created in a ViewLegend, it is treated as a legend representation of what a RevisionCloud looks like rather than as an actual indication of a change to the model. As a result, RevisionClouds in ViewLegends will not affect the contents of revision schedules.
|
||||
|
||||
### Creating revision clouds
|
||||
|
||||
The static Create() methodallows an application to create a new RevisionCloud in a specified view based on a series of lines and curves. RevisionClouds can only be created if the associated Revision has not yet been issued.
|
||||
|
||||
RevisionClouds can be created in most graphical Views, excepting 3D views and graphical column schedules. Unlike most other Elements, RevisionClouds can be created directly on a ViewSheet.
|
||||
|
||||
RevisionClouds are created based on a series of sketched curves. There is no requirement that the curves form closed loops and self-intersections are also permitted. The curves will be automatically projected onto the appropriate plane for the View. The list of curves cannot be empty and no lines can be perpendicular to the View's plane. If the View is a model View, the coordinates specified for the curves will be interpreted in model space. If the View is a non-model View (such as a ViewSheet) then the coordinates will be interpreted in the View's space.
|
||||
|
||||
Each curve will have a series of "cloud bumps" drawn along it to form the appearance of a cloud. The cloud graphics will be attached to the curves under the assumption that each curve is oriented in a clockwise direction. For lines, this means that the outside of the cloud is in the direction of the line's normal vector within the View's plane. Any closed loops should therefore be oriented clockwise to create the typical cloud shape.
|
||||
|
||||
Code Region: Create revision cloud
|
||||
---
|
||||
|
||||
|
||||
private void CreateRevisionCloudInActiveView(Document document, Revision revision, IList<Curve> curves)
|
||||
{
|
||||
using (Transaction newRevisionCloud = new Transaction(document, "Create Revision Cloud"))
|
||||
{
|
||||
newRevisionCloud.Start();
|
||||
// Can only create revision cloud for revision that is not issued
|
||||
if (revision.Issued == false)
|
||||
{
|
||||
RevisionCloud.Create(document, document.ActiveView, revision.Id, curves);
|
||||
newRevisionCloud.Commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
newRevisionCloud.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### Revision cloud geometry
|
||||
|
||||
RevisionCloud is derived from the Element class. The Element.Geometry property for revision clouds will return the actual curved lines that make up the cloud. The RevisionCloud.GetSketchCurves() method on the other hand,will return the sketched curves that define the basic outline of the cloud and not the arcs that Revit attaches to these curves to create the cloud appearance.
|
||||
|
||||
### Revision Associated with RevisionCloud
|
||||
|
||||
Each RevisionCloud is associated with one Revision. The associated revision id is specified when calling Create() and can be retrieved from the RevisionCloud.RevisionId property. The RevisionId property for a RevisionCloud can be changed if it is not associated with a Revision that has already been issued. It can only be changed to the id of another Revision that has also not been issued. RevisionCloud.IsRevisionIssued() returns whether the associated Revision has been issued.
|
||||
|
||||
### ViewSheets
|
||||
|
||||
When a RevisionCloud is visible on a ViewSheet (either because it is directly placed on that ViewSheet or because it is visible in a View placed on the ViewSheet), any revision schedules displayed on the ViewSheet will automatically include the Revision associated with the RevisionCloud.
|
||||
|
||||
The RevisionCloud.GetSheetIds() method returns the ids of the ViewSheets where it may appear and contribute to the sheet's revision schedule. A RevisionCloud can appear on a ViewSheet because it is drawn directly on the ViewSheet or because its owner view is placed on the ViewSheet. If the RevisionCloud is owned by a view that is a dependent view or has associated dependent views, then the RevisionCloud can also be visible on the sheets where the related dependent or primary views have been placed.
|
||||
|
||||
This RevisionCloud may not be visible in all ViewSheets reported by this method. Additional factors, such as the visibility settings or annotation crop of the Views or the visibility settings of the associated Revision may still cause this RevisionCloud to not appear on a particular ViewSheet.
|
||||
|
||||
If this RevisionCloud is owned by a ViewLegend, no sheets will be returned because the RevisionCloud will not participate in revision schedules. The ViewSheet class includes methods for working with Revisions and RevisionClouds on sheets. See the [ViewSheet](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_ViewSheet_html.html) topic for more information.
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,59 @@
|
||||
# Temporary Graphics
|
||||
|
||||
# Temporary Graphics
|
||||
|
||||
The `TemporaryGraphicsManager` class allows you to create temporary graphics in Revit views. The graphics created by this class are not subject to undo and are not saved. The Revit API developer should manage their lifetime, creation and destruction, though Revit will destroy all of them when closing the model.
|
||||
|
||||
The `AddControl` method creates a control in a specified view based on an instance of the `InCanvasControlData` class which defines the image path and location in model coordinates of the control. Additional functionality exists in the methods:
|
||||
|
||||
* RemoveControl
|
||||
* SetVisibility
|
||||
* UpdateControl
|
||||
|
||||
|
||||
|
||||
The method TemporaryGraphicsManager.SetTooltip() sets the tooltip for the given temporary graphics object.
|
||||
|
||||
This code sample creates a temporary control at the center of a wall. The website, [www.autodesk.com](http://www.autodesk.com), is opened when the user clicks on the control. The `OnClick` method is implemented in a server class that derives from `ITemporaryGraphicsHandler`.
|
||||
|
||||
**Code Region: Creating a Temporary Control**
|
||||
|
||||
|
||||
private void TemporaryGraphicsControl(Wall wall)
|
||||
{
|
||||
Document doc = wall.Document;
|
||||
|
||||
MultiServerService externalService = ExternalServiceRegistry.GetService(
|
||||
ExternalServices.BuiltInExternalServices.TemporaryGraphicsHandlerService) as MultiServerService;
|
||||
MyGraphicsService myGraphicsService = new MyGraphicsService();
|
||||
externalService.AddServer(myGraphicsService);
|
||||
externalService.SetActiveServers(
|
||||
new List<Guid> {myGraphicsService.GetServerId()});
|
||||
|
||||
TemporaryGraphicsManager mgr = TemporaryGraphicsManager.GetTemporaryGraphicsManager(doc);
|
||||
XYZ controlPoint = ((LocationCurve)wall.Location).Curve.Evaluate(0.5, true);
|
||||
InCanvasControlData data = new InCanvasControlData(
|
||||
@"C:/Autodesk/image32.bmp",
|
||||
controlPoint);
|
||||
mgr.AddControl(data, doc.ActiveView.Id);
|
||||
}
|
||||
|
||||
public class MyGraphicsService: ITemporaryGraphicsHandler
|
||||
{
|
||||
public void OnClick(TemporaryGraphicsCommandData data)
|
||||
{
|
||||
Process.Start("https://www.autodesk.com");
|
||||
}
|
||||
public string GetName()
|
||||
{ return "My Graphics Service"; }
|
||||
public string GetDescription()
|
||||
{ return "This is a graphics service"; }
|
||||
public string GetVendorId()
|
||||
{ return "ADSK"; }
|
||||
public ExternalServiceId GetServiceId()
|
||||
{ return ExternalServices.BuiltInExternalServices.TemporaryGraphicsHandlerService; }
|
||||
public Guid GetServerId()
|
||||
{ return new Guid("a8debc37-19fe-4198-1198-01a891ff1a7f"); }
|
||||
}
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,19 @@
|
||||
# UIView
|
||||
|
||||
# UIView
|
||||
|
||||
While the View class is the base class for all view types in Revit and keeps tracks of elements in the view, the UIView class contains data about the view windows in the Revit user interface. A list of all open views can be retrieved from the UIDocument using the GetOpenUIViews() method. The UIView class has methods to get information about the views drawing area as well as to pan and zoom the active view.
|
||||
|
||||
UIView.GetWindowRectangle() returns a rectangle that describes the size and placement of the UIView window. It does not include the window border or title bar.
|
||||
|
||||
### Zoom Operations
|
||||
|
||||
UIView has several methods related to zooming the active view. UIView.GetZoomCorners() gets the corners of the view's rectangle in model coordinates and UIView.ZoomAndCenterRectangle() offers the ability to zoom and pan the active view to center on the input region of the model.
|
||||
|
||||
The ZoomToFit() and ZoomSheetSize() methods provide quick ways to adjust the zoom of the window, while the Zoom() method can be used to zoom in or out by a specified factor.
|
||||
|
||||
### Closing a View
|
||||
|
||||
UIView.Close() can close a visible window. However, it cannot be used to close the last active window. Attempting to close the last active window will throw an exception.
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,35 @@
|
||||
# View Cropping
|
||||
|
||||
# View Cropping
|
||||
|
||||
The crop region for some views may be modified using the Revit API. The ViewCropRegionShapeManager.CanHaveShape property indicates whether the view is allowed to manage the crop region shape while the ShapeSet property indicates whether a shape has been set. The following example crops a view around the boundary of a room.
|
||||
|
||||
**Code Region: Cropping a view**
|
||||
---
|
||||
|
||||
|
||||
public void CropAroundRoom(Room room, View view)
|
||||
{
|
||||
if (view != null)
|
||||
{
|
||||
IList<IList<Autodesk.Revit.DB.BoundarySegment>> segments = room.GetBoundarySegments(new SpatialElementBoundaryOptions());
|
||||
|
||||
if (null != segments) //the room may not be bound
|
||||
{
|
||||
foreach (IList<Autodesk.Revit.DB.BoundarySegment> segmentList in segments)
|
||||
{
|
||||
CurveLoop loop = new CurveLoop();
|
||||
foreach (Autodesk.Revit.DB.BoundarySegment boundarySegment in segmentList)
|
||||
{
|
||||
loop.Append(boundarySegment.GetCurve());
|
||||
}
|
||||
|
||||
ViewCropRegionShapeManager vcrShapeMgr = view.GetCropRegionShapeManager();
|
||||
vcrShapeMgr.SetCropShape(loop);
|
||||
break; // if more than one set of boundary segments for room, crop around the first one
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,198 @@
|
||||
# View Filters
|
||||
|
||||
# View Filters
|
||||
|
||||
Filters are elements independent of views. They can be applied to Views using the ParameterFilterElement class or a SelectionFilterElement class.
|
||||
|
||||
### ParameterFilterElement
|
||||
|
||||
A ParameterFilterElement filters elements based on the elements’ categories and an ElementFilter. The ElementFilter must be either an ElementParameterFilter or an ElementLogicalFilter containing only ElementParameterFilters and other ElementLogicalFilters. This allows the view filter to be constructed from a combination of AND and OR filters that are then gathered by an AND filter, an OR filter, or an ElementParameterFilter as an input to ParameterFilterElement.Create().
|
||||
|
||||
Once a filter has been defined (with one or more categories and zero or more filter rules), it can be applied to a View using one of several methods. The View.AddFilter() method will apply the filter to the view, but with default overrides, meaning the view's display will not change. View.SetFilterOverrides() sets graphical overrides associated with a filter. Setting elements that pass a filter to not be visibile in a view is done with View.SetFilterVisibility(ElementId filterElementId, bool visibility). AddFilter() and SetFilterVisibility() will both apply the filter to the view if it is not already applied, making it unnecessary to call AddFilter() separately.
|
||||
|
||||
#### Validation
|
||||
|
||||
Validation restrictions for the ElementFilter stored by a ParameterFilterElement (the class that represents a View Filter) support flexible creation of OR filters where criteria can reference parameters only associated to specific categories. The ElementFilter must be either an ElementParameterFilter or an ElementLogicalFilter representing a Boolean combination of ElementParameterFilters.
|
||||
|
||||
In addition, Revit checks that each ElementParameterFilter satisfies the following conditions:
|
||||
|
||||
* Its array of FilterRules is not empty and contains:
|
||||
* Any number of FilterRules of type FilterValueRule, FilterInverseRule, and SharedParameterApplicableRule or
|
||||
* Exactly one FilterCategoryRule containing only one category from categories stored by this ParameterFilterElement or
|
||||
* Exactly two rules: the first one is a FilterCategoryRule containing only one category from categories stored by this ParameterFilterElement and the second one is a FilterRule of type FilterValueRule, FilterInverseRule, or SharedParameterApplicableRule.
|
||||
|
||||
|
||||
|
||||
Cases in the second and third bullet are currently allowed only if the parent node of ElementParameterFilter is LogicalOrFilter.
|
||||
|
||||
The method `ParameterFilterElement.GetElementFilterParametersForCategory()` retrieves a list of the parameters associated with all rules in the filter that are combined (using logical AND) with a FilterCategoryRule corresponding to single categoryId.
|
||||
|
||||
These methods identify or set if the filter is enabled in this view:
|
||||
|
||||
* View.GetIsFilterEnabled()
|
||||
* View.SetIsFilterEnabled()
|
||||
|
||||
|
||||
|
||||
`View.GetOrderedFilters()` gets the filters applied to the view in the order they are applied.
|
||||
|
||||
The following example creates a new view filter matching multiple criteria and then hides those elements in the view.
|
||||
|
||||
**Code Region: Applying a parameter filter to a view**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateViewFilter(Document doc, View view)
|
||||
{
|
||||
List<ElementId> categories = new List<ElementId>();
|
||||
categories.Add(new ElementId(BuiltInCategory.OST_Walls));
|
||||
List<ElementFilter> elementFilterList = new List<ElementFilter>();
|
||||
|
||||
using (Transaction t = new Transaction(doc, "Add view filter"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
// Criterion 1 - wall type Function is "Exterior"
|
||||
ElementId exteriorParamId = new ElementId(BuiltInParameter.FUNCTION_PARAM);
|
||||
elementFilterList.Add(new ElementParameterFilter(ParameterFilterRuleFactory.CreateEqualsRule(exteriorParamId, (int)WallFunction.Exterior)));
|
||||
|
||||
// Criterion 2 - wall length > = 28 or < = 14
|
||||
ElementId lengthId = new ElementId(BuiltInParameter.CURVE_ELEM_LENGTH);
|
||||
LogicalOrFilter wallHeightFilter = new LogicalOrFilter(
|
||||
new ElementParameterFilter(ParameterFilterRuleFactory.CreateGreaterOrEqualRule(lengthId, 28.0, 0.00001)),
|
||||
new ElementParameterFilter(ParameterFilterRuleFactory.CreateLessOrEqualRule(lengthId, 14.0, 0.00001)));
|
||||
elementFilterList.Add(wallHeightFilter);
|
||||
|
||||
// Criterion 3 - custom shared parameter value matches string pattern
|
||||
// Get the id for the shared parameter - the ElementId is not hardcoded, so we need to get an instance of this type to find it
|
||||
Guid spGuid = new Guid("96b00b61-7f5a-4f36-a828-5cd07890a02a");
|
||||
FilteredElementCollector collector = new FilteredElementCollector(doc);
|
||||
collector.OfClass(typeof(Wall));
|
||||
Wall wall = collector.FirstElement() as Wall;
|
||||
|
||||
if (wall != null)
|
||||
{
|
||||
Parameter sharedParam = wall.get_Parameter(spGuid);
|
||||
ElementId sharedParamId = sharedParam.Id;
|
||||
|
||||
elementFilterList.Add(new ElementParameterFilter(ParameterFilterRuleFactory.CreateBeginsWithRule(sharedParamId, "15.")));
|
||||
}
|
||||
|
||||
// Create filter element associated to the input categories
|
||||
LogicalAndFilter andFilter = new LogicalAndFilter(elementFilterList);
|
||||
if (ParameterFilterElement.ElementFilterIsAcceptableForParameterFilterElement(doc, new HashSet<ElementId>(categories), andFilter))
|
||||
{
|
||||
ParameterFilterElement parameterFilterElement = ParameterFilterElement.Create(doc, "Example view filter", categories, andFilter);
|
||||
|
||||
// Apply filter to view
|
||||
view.AddFilter(parameterFilterElement.Id);
|
||||
view.SetFilterVisibility(parameterFilterElement.Id, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskDialog.Show("Error", "Filter cannot be used");
|
||||
}
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
### SelectionFilterElement
|
||||
|
||||
A SelectionFilterElement is a special view filter not based on rules, but on a group of possibly unrelated elements. Specific elements can be added to the filter as required and the resulting selection can be overridden just like ParameterFilterElement.
|
||||
|
||||
The following example creates a new selection filter and applies an override to it.
|
||||
|
||||
**Code Region: Applying a selection filter to a view**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateSelectionFilter(Document doc, View view)
|
||||
{
|
||||
// find room tags in this view
|
||||
FilteredElementCollector collector = new FilteredElementCollector(doc, view.Id);
|
||||
collector.WherePasses(new RoomTagFilter());
|
||||
|
||||
// collect tags whose room number matches criteria
|
||||
List<ElementId> tagIds = new List<ElementId>();
|
||||
|
||||
foreach (RoomTag tag in collector.Cast<RoomTag>())
|
||||
{
|
||||
int number = Int32.Parse(tag.Room.Number);
|
||||
if (number % 3 == 0)
|
||||
{
|
||||
tagIds.Add(tag.Id);
|
||||
}
|
||||
}
|
||||
|
||||
using (Transaction t = new Transaction(doc, "Create SelectionFilterElement"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
// Create selection filter and assign ids
|
||||
SelectionFilterElement filterElement = SelectionFilterElement.Create(doc, "Room tags filter");
|
||||
filterElement.SetElementIds(tagIds);
|
||||
|
||||
ElementId filterId = filterElement.Id;
|
||||
|
||||
// Add the filter to the view
|
||||
view.AddFilter(filterId);
|
||||
|
||||
doc.Regenerate();
|
||||
|
||||
// Use the existing graphics settings, and change the color to Blue
|
||||
OverrideGraphicSettings overrideSettings = view.GetFilterOverrides(filterId);
|
||||
|
||||
overrideSettings.SetProjectionLineColor(new Color(0x00, 0x00, 0xFF));
|
||||
|
||||
view.SetFilterOverrides(filterId, overrideSettings);
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
### Modifying filters
|
||||
|
||||
All filters applied to a view can be retrieved using the View.GetFilters() method which will return a list of filter ids. Filter visibility and graphic overrides can be checked for a specific filter using the View.GetFilterVisibility() and View.GetFilterOverrides() methods respectively. View.RemoveFilter will remove a filter from the view.
|
||||
|
||||
The following example demonstrates how to get the filters in a view and then modifies the overrides associated with any filter currently setting the cut color to red.
|
||||
|
||||
**Code Region: Modify existing filter**
|
||||
---
|
||||
|
||||
|
||||
public static void ModifyExistingFilter(Document doc, View view)
|
||||
{
|
||||
// Find any filter with overrides setting cut color to Red
|
||||
Dictionary<ElementId, OverrideGraphicSettings> filterIdsToChange = new Dictionary<ElementId, OverrideGraphicSettings>();
|
||||
|
||||
foreach (ElementId filterId in view.GetFilters())
|
||||
{
|
||||
OverrideGraphicSettings overrideSettings = view.GetFilterOverrides(filterId);
|
||||
|
||||
Color lineColor = overrideSettings.CutLineColor;
|
||||
|
||||
if (lineColor == Color.InvalidColorValue)
|
||||
continue;
|
||||
|
||||
// Save overrides setting the cut color to green
|
||||
if (lineColor.Red == 0xFF && lineColor.Green == 0x00 && lineColor.Blue == 0x00)
|
||||
{
|
||||
overrideSettings.SetCutLineColor(new Color(0x00, 0xFF, 0x00));
|
||||
filterIdsToChange[filterId] = overrideSettings;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the change to all found filters
|
||||
using (Transaction t = new Transaction(doc, "Change override filters"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
foreach (ElementId filterId in filterIdsToChange.Keys)
|
||||
{
|
||||
view.SetFilterOverrides(filterId, filterIdsToChange[filterId]);
|
||||
}
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,205 @@
|
||||
# View Graphics
|
||||
|
||||
# View Graphics
|
||||
|
||||
Many elements of the graphics and display options for views are exposed via the API.
|
||||
|
||||
## Display settings
|
||||
|
||||
The view class has properties to get and set the display style settings and the detail level settings. The View.DisplayStyle property uses the DisplayStyle enumeration and corresponds to the display options available at the bottom of the Revit window as shown below.
|
||||
|
||||
Note: The display style cannot be set to Raytrace from the Revit API because this display style puts Revit into a restricted mode with limited capabilities.
|
||||
|
||||
The View.DetailLevel property uses the ViewDetailLevel enumeration and corresponds to the detail level options available at the bottom of the Revit window as shown below.
|
||||
|
||||
The ViewDetailLevel enumeration includes Undefined in the case that a given View does not use detail level.
|
||||
|
||||
## Thin Lines
|
||||
|
||||
The Thin Lines option, available in the Revit UI on the Graphics panel of the View tab, controls how lines are drawn in a view. Typically, when you zoom in on a model in a small scale view, element lines appear much thicker than they actually are. When Thin Lines is enabled, all lines are drawn as a single width regardless of zoom level. This option is made available via the ThinLinesOptions utility class, which has a property called AreThinLinesEnabled. It is a static property which affects the entire Revit session.
|
||||
|
||||
## Temporary view modes
|
||||
|
||||
The TemporaryViewModes class allows for control of temporary view modes. It can be accessed from the View.TemporaryViewModes property. For views that do not support temporary view modes, this property will be null. The RevealConstraints, RevealHiddenElements and WorksharingDisplay properties can be used to get and set the current state of these modes in the corresponding view. Note that some modes are only available in certain views and/or in a certain context. Additionally an available mode is not necessarily enabled in the current context. The TemporaryViewModes methods IsModeAvailable() and IsModeEnabled() can be used to test that a particular mode is both available and enabled before use. These methods take a TemporaryViewMode enum. The possible options are shown below.
|
||||
|
||||
TemporaryViewModes.AcceleratedGraphicsMode - Represents the current state of the Accelerated Graphics mode in the associated view.
|
||||
|
||||
AcceleratedGraphicsMode - Represents the view is in the mode that shows Accelerated Graphics.
|
||||
|
||||
**Member Name** | **Description**
|
||||
---|---
|
||||
RevealHiddenElements | The reveal hidden elements mode
|
||||
TemporaryHideIsolate | The temporary hide/isolate mode
|
||||
WorksharingDisplay | One of the worksharing display modes
|
||||
TemporaryViewProperties | The temporary View Properties mode
|
||||
ExplodedView | The mode that shows the model in exploded view and allows user changes/configurations
|
||||
RevealConstraints | The mode that reveals constraints between elements in the model
|
||||
**Code Region: Reveal hidden elements in a view**
|
||||
---
|
||||
|
||||
|
||||
public bool RevealHiddenElementsInView(View view)
|
||||
{
|
||||
bool hiddenRevealed = false;
|
||||
TemporaryViewModes viewModes = view.TemporaryViewModes;
|
||||
|
||||
if (viewModes == null)
|
||||
{
|
||||
TaskDialog.Show("Invalid View", "This view does not support temporary view modes.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mode must be available and enabled to be activated
|
||||
if (viewModes.IsModeEnabled(TemporaryViewMode.RevealHiddenElements) && viewModes.IsModeAvailable(TemporaryViewMode.RevealHiddenElements))
|
||||
{
|
||||
viewModes.RevealHiddenElements = true;
|
||||
hiddenRevealed = viewModes.RevealHiddenElements;
|
||||
}
|
||||
}
|
||||
|
||||
return hiddenRevealed;
|
||||
}
|
||||
|
||||
The TemporaryViewModes.IsModeActive() method tests whether a given mode is currently active in the view. Use the DeactivateAllModes() method to deactivate all currently active views, or use DeactiveMode() to deactivate a specific mode.
|
||||
|
||||
The PreviewFamilyVisibility property gets and sets the current state of the PreviewFamilyVisibility mode in the associated view. This mode is only available when the document of the view is in the environment of the family editor. This property is a PreviewFamilyVisibilityMode enumerated value rather than a bool. Possible states for this mode are:
|
||||
|
||||
**Member Name** | **Description**
|
||||
---|---
|
||||
Off | Element Visibility is not applied. All family elements visible.
|
||||
On | Element Visibility of a view is applied to show visible elements only. Elements that are cut by a reference plane will be shown with their respective cut geometry.
|
||||
Uncut | Element Visibility of a view is applied to show elements visible if instance is not cut. Note that this state is only available in certain views, such as floor plan and ceilings.
|
||||
|
||||
Even if the PreviewFamilyVisibility mode is available and enabled for a view, not all states are valid in all views. Before applying one of these states to a view, call IsValidState() to ensure it can be applied.
|
||||
|
||||
**Code Region: Turn off preview family visibility mode**
|
||||
---
|
||||
|
||||
|
||||
public void TurnOffFamilyVisibilityMode(View view)
|
||||
{
|
||||
TemporaryViewModes viewModes = view.TemporaryViewModes;
|
||||
|
||||
if (viewModes != null)
|
||||
{
|
||||
if (viewModes.IsModeAvailable(TemporaryViewMode.PreviewFamilyVisibility) && viewModes.IsModeEnabled(TemporaryViewMode.PreviewFamilyVisibility))
|
||||
{
|
||||
if (viewModes.IsValidState(PreviewFamilyVisibilityMode.Off))
|
||||
{
|
||||
viewModes.PreviewFamilyVisibility = PreviewFamilyVisibilityMode.Off;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
When a view is opened for the first time, its state of the PreviewFamilyVisibility mode is determined based on the default settings which is controlled through the static TemporaryViewModes properties PreviewFamilyVisibilityDefaultOnState and PreviewFamilyVisibilityDefaultUncutState as shown below.
|
||||
|
||||
**Code Region: Set default preview family visibility state**
|
||||
---
|
||||
|
||||
|
||||
public void SetDefaultPreviewFamilyVisibilityState()
|
||||
{
|
||||
TemporaryViewModes.PreviewFamilyVisibilityDefaultOnState = true;
|
||||
TemporaryViewModes.PreviewFamilyVisibilityDefaultUncutState = true;
|
||||
}
|
||||
|
||||
The PreviewFamilyVisibilityDefaultOnState value controls whether each newly opened view is to have the PreviewFamilyVisibility mode turned On by default or not. This property is applicable to all types of views. Views that support both cut and uncut previews (such as floor plans) will use the cut/uncut state indicated by the PreviewFamilyVisibilityDefaultUncutState property, but only if the PreviewFamilyVisibilityDefaultOnState property is set to true.
|
||||
|
||||
These settings are applicable to the whole application rather than to individual family documents; the values persists between Revit sessions. Although the value is allowed to be set at any time, any changes made after the Revit application has been initialized will not have effect until the next session of Revit.
|
||||
|
||||
Note that once the PreviewFamilyVisibility property is explicitly modified, the applied setting stays in effect for the respective view even after the view is closed and later reopened again.
|
||||
|
||||
### Custom Temporary View Modes
|
||||
|
||||
The Revit API allows customization to create "custom temporary view modes" applied to a view as a temporary view property. For example, the "Reveal Obstacles for Path of Travel" temporary mode is implemented this way. It uses the Analysis Visualization Framework (AVF) to display additional graphics on top of the view contents.
|
||||
|
||||
These properties provide access to read and modify a custom temporary view mode. `CustomTitle` should be set to cause the view to display the customized frame. The application is responsible to adjust the appearance of elements in the view related to the mode.
|
||||
|
||||
* TemporaryViewModes.CustomTitle
|
||||
* TemporaryViewModes.CustomColor
|
||||
* TemporaryViewModes.RemoveCustomization()
|
||||
* TemporaryViewModes.IsCustomized()
|
||||
|
||||
|
||||
|
||||
## Element visibility in a view
|
||||
|
||||
Views keep track of visible elements. All elements that are graphical and visible in the view can be retrieved using a FilteredElementCollector constructed with a document and the id of the view. However, some elements in the set may be hidden or covered by other elements. You can see them by rotating the view or removing the elements that cover them. Accessing these visible elements may require Revit to rebuild the geometry of the view. The first time your code uses this constructor for a given view, or the first time your code uses this constructor for a view whose display settings have just been changed, you may experience a significant performance degradation.
|
||||
|
||||
Individual elements can be hidden in a particular view. The method Element.IsHidden() indicates if an element is hidden in the given view, and Element.CanBeHidden() returns whether the element can be hidden. To hide individual elements, use View.HideElements() which takes a collection of ElementIds corresponding to the elements you wish to hide.
|
||||
|
||||
Element visibility can also be changed by category.
|
||||
|
||||
* The View.GetCategoryHidden() method queries a category id to determine if it is hidden or visible in the view.
|
||||
* The View.SetCategoryHidden() method sets all elements in a specific category to hidden or visible.
|
||||
* The View.CanCategoryBeHidden() method indicates if a specific category of elements can be hidden in the view.
|
||||
|
||||
|
||||
|
||||
A FilteredElementCollector based on a view will only contain elements visible in the current view. You cannot retrieve elements that are not graphical or elements that are invisible. A FilteredElementCollector based on a document retrieves all elements in the document including invisible elements and non-graphical elements. For example, when creating a default 3D view in an empty project, there are no elements in the view but there are many elements in the document, all of which are invisible.
|
||||
|
||||
The following code sample counts the number of wall category elements in the active document and active view. The number of elements in the active view differs from the number of elements in the document since the document contains non-graphical wall category elements.
|
||||
|
||||
**Code Region: Counting elements in the active view**
|
||||
---
|
||||
|
||||
|
||||
private void CountElements(UIDocument uiDoc)
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
FilteredElementCollector viewCollector =
|
||||
new FilteredElementCollector(uiDoc.Document, uiDoc.ActiveView.Id);
|
||||
viewCollector.OfCategory(BuiltInCategory.OST_Walls);
|
||||
message.AppendLine("Wall category elements within active View: "
|
||||
+ viewCollector.ToElementIds().Count);
|
||||
|
||||
FilteredElementCollector docCollector = new FilteredElementCollector(uiDoc.Document);
|
||||
docCollector.OfCategory(BuiltInCategory.OST_Walls);
|
||||
message.AppendLine("Wall category elements within document: "
|
||||
+ docCollector.ToElementIds().Count);
|
||||
|
||||
TaskDialog.Show("Revit", message.ToString());
|
||||
}
|
||||
|
||||
Temporary view modes can affect element visibility. The View.IsInTemporaryViewMode() method can be used to determine if a View is in a temporary view mode. The method View.IsElementVisibleInTemporaryViewMode() identifies if an element should be visible in the indicated view mode. This applies only to the TemporaryHideIsolate and AnalyticalModel view modes. Other modes will result in an exception.
|
||||
|
||||
## Depth Cueing
|
||||
|
||||
The ViewDisplayDepthCueing class provides control of the display of distant objects in section and elevation views. When depth cueing is active, objects blend into the background color (fade) with increasing distance from the viewer. The current depth cueing settings for a view can be retrieved using View.GetDepthCueing(). If changes are made to the returned ViewDisplayDepthCueing, they will not be applied to the view until calling View.SetDepthCueing().
|
||||
|
||||
The ViewDisplayDepthCueing class has the following properties:
|
||||
|
||||
**Member Name** | **Description**
|
||||
---|---
|
||||
EnableDepthCueing | True to enable depth cueing.
|
||||
StartPercentage | Indicates where depth cueing begins. A value of 0 indicates that depth cueing begins at the front clip plane of the view.
|
||||
EndPercentage | Indicates where depth cueing ends. Objects further than the end plane will fade the same amount as objects at the end plane. A value of 100 indicates the far clip plane.
|
||||
FadeTo | Indicates the maximum amount to fade objects via depth cueing. A value of 100 indicates complete invisibility.
|
||||
|
||||
The SetStartEndPercentages() method can be used to set the start and end percentages in one call.
|
||||
|
||||
The following example demonstrates how to get the current depth cueing, change its properties and set it back to the view. Note that not all views can use depth cueing.
|
||||
|
||||
**Code Region: Change the depth cueing for a view**
|
||||
---
|
||||
|
||||
|
||||
private void AdjustDepthCueing(View view)
|
||||
{
|
||||
if (view.CanUseDepthCueing())
|
||||
{
|
||||
using (Transaction t = new Transaction(view.Document, "Change depth cueing"))
|
||||
{
|
||||
t.Start();
|
||||
ViewDisplayDepthCueing depthCueing = view.GetDepthCueing();
|
||||
depthCueing.EnableDepthCueing = true;
|
||||
depthCueing.FadeTo = 50; // set fade to percent
|
||||
depthCueing.SetStartEndPercentages(0, 75);
|
||||
view.SetDepthCueing(depthCueing);
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,105 @@
|
||||
# View Templates
|
||||
|
||||
# View Templates
|
||||
|
||||
A View Template is a special kind of View that can controls parameters of views that display elements in the Revit model. View Templates themselves do not display Revit elements.
|
||||
|
||||
## Basic functions that can be used with View Templates
|
||||
|
||||
* `View.CreateViewTemplate()` \- Creates a new view template instance from the view instance
|
||||
* `View.IsViewValidForTemplateCreation()` \- Verifies that the view is valid for template creation
|
||||
* `View.IsTemplate` \- Test whether the view is a view template
|
||||
* `View.IsValidViewTemplate(ElementId templateId)` \- Verifies that the view represented by templateId can be set as the controlling view template for this view
|
||||
* `View.ViewTemplateId` \- The id of the template view that controls this view's parameters
|
||||
* `IList<ElementId>` View.GetTemplateParameterIds() - Returns a list of parameter ids that may be controlled when this view is assigned as a template
|
||||
* `ICollection<ElementId>` View.GetNonControlledTemplateParameterIds() - Returns a list of parameters that are not marked as included when this view is used as a template
|
||||
* `View.SetNonControlledTemplateParameterIds(ICollection<ElementId> newSet)` \- Sets the parameters that will not be included when this view is used as a template
|
||||
|
||||
|
||||
|
||||
Below is list of controllable built-in parameters along with references to their respective API getters/setters.
|
||||
|
||||
Parameter Name in View Templates Dialog | View Template Parameter Name | View Type Limitations | API getters/setters | Comments
|
||||
---|---|---|---|---
|
||||
View Scale Scale Value | VIEW_SCALE | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.Scale property | To include/exclude in non-controlled parameters set, VIEW_SCALE has to be usedtogether with with the following parameters: VIEW_SCALE_PULLDOWN_IMPERIAL VIEW_SCALE_PULLDOWN_METRIC
|
||||
Display Model | VIEW_MODEL_DISPLAY_MODE | Valid for all plan views, Section, Elevation, Detail | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) | Valid values are 0 (Normal), 1 (Halftone) and 2 (Do not display)
|
||||
Detail Level | VIEW_DETAIL_LEVEL | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.DetailLevel property | Use also View.CanModifyDetailLevel() and View.HasDetailLevel()
|
||||
Parts Visibility | VIEW_PARTS_VISIBILITY | Valid for all plan views, all 3D views, Section, Elevation, Detail | View.PartsVisibility property |
|
||||
V/G Overrides Model | VIS_GRAPHICS_MODEL | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetCategoryOverrides
|
||||
View.SetCategoryOverrides |
|
||||
V/G Overrides Annotation | VIS_GRAPHICS_ANNOTATION | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetCategoryOverrides
|
||||
View.SetCategoryOverrides |
|
||||
V/G Overrides Analytical Model | VIS_GRAPHICS_ANALYTICAL_MODEL | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetCategoryOverrides
|
||||
View.SetCategoryOverrides |
|
||||
V/G Overrides Import | VIS_GRAPHICS_IMPORT | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetCategoryOverrides
|
||||
View.SetCategoryOverrides | Imported categories are not built-in, so they can be found using other API operations
|
||||
V/G Overrides Filters | VIS_GRAPHICS_FILTERS | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetFilters
|
||||
View.GetFilterOverrides
|
||||
View.SetFilterOverrides |
|
||||
V/G Overrides Worksets | VIS_GRAPHICS_WORKSETS | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetWorksetVisibility
|
||||
View.SetWorksetVisibility | Valid only if Document.IsWorkshared() is true
|
||||
Use also View.IsWorksetVisible(<28>)
|
||||
V/G Overrides RVT Links | VIS_GRAPHICS_RVT_LINKS | Valid for all plan views, all 3D views, Section, Elevation, Detail | No API access at the time (Revit 2020) | Valid only if Revit links are present in the document
|
||||
V/G Overrides Point Clouds | VIS_GRAPHICS_POINT_CLOUDS | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetPointCloudOverrides
|
||||
View.SetPointCloudOverrides | Valid only if PointCloudInstance elements are present in the document
|
||||
Use also View.ArePointCloudsHidden()
|
||||
V/G Overrides Coordination Model | VIS_GRAPHICS_COORDINATION_MODEL | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.GetDirectContext3DHandleOverrides | Valid only if NavisWorks coordination models are linked in the document
|
||||
V/G Overrides Design Options | VIS_GRAPHICS_DESIGN_OPTIONS | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView, all schedules | No API access at the time (Revit 2020) | Valid only if design options other than <20>Main Model<65> are present in the document
|
||||
Model Display | GRAPHIC_DISPLAY_OPTIONS_MODEL | Valid for all plan views, all 3D views, Section, Elevation, Detail | View.GetViewDisplayModel
|
||||
View.SetViewDisplayModel |
|
||||
Shadow | GRAPHIC_DISPLAY_OPTIONS_SHADOW | Valid for all plan views, all 3D views, Section, Elevation, Detail | No API access at the time (Revit 2020) |
|
||||
Sketchy Lines | GRAPHIC_DISPLAY_OPTIONS_SKETCHY_LINES | Valid for all plan views, all 3D views, Section, Elevation, Detail | View.GetSketchyLines
|
||||
View.SetSketchyLines |
|
||||
Depth Cueing | GRAPHIC_DISPLAY_OPTIONS_FOG | Valid for all plan views, all 3D views, Section, Elevation, Detail | View.GetDepthCueing
|
||||
View.SetDepthCueing | Use also View.CanUseDepthCueing()
|
||||
Lighting | GRAPHIC_DISPLAY_OPTIONS_LIGHTING | Valid for all plan views, all 3D views, Section, Elevation, Detail | Partial API access at the time (Revit 2020):
|
||||
View.ShadowIntensity property
|
||||
View.SunLightIntensity property |
|
||||
Photographic Exposure | GRAPHIC_DISPLAY_OPTIONS_PHOTO_EXPOSURE | Valid for all plan views, all 3D views, Section, Elevation, Detail | API access provided only for 3D views:
|
||||
View3D.GetRenderingSettings
|
||||
View3D.SetRenderingSettings |
|
||||
Background | GRAPHIC_DISPLAY_OPTIONS_BACKGROUND | Valid for all plan views, all 3D views, Section, Elevation, Detail | View.GetBackground
|
||||
View.SetBackGround |
|
||||
Far Clipping | VIEWER_BOUND_FAR_CLIPPING | Section, Elevation, Detail | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) |
|
||||
Phase Filter | VIEW_PHASE_FILTER | Valid for all plan views, all 3D views, Section, Elevation, Detail, all schedules | Element.Parameter.AsElementId()
|
||||
Element.Parameter.Set(ElementId) |
|
||||
Discipline | VIEW_DISCIPLINE | Valid for all plan views, all 3D views, Section, Elevation, Detail, DraftingView | View.Discipline property |
|
||||
Show Hidden Lines | VIEW_SHOW_HIDDEN_LINES | Valid for all plan views, all 3D views, Section, Elevation, Detail | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) | Valid values are 0 (None), 1 (By Discipline), 2 (All)
|
||||
Color Scheme Location | COLOR_SCHEME_LOCATION | Valid for all plan views except for ceiling, Section, Elevation, Detail | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) | Valid values are 0 (Foreground), 1 (Background)
|
||||
Color Scheme | VIEW_SCHEMA_SETTING_FOR_BUILDING | Valid for all plan views except for ceiling, Section, Elevation, Detail | No API access at the time (Revit 2020) |
|
||||
Underlay Orientation | VIEW_UNDERLAY_ORIENTATION | Valid for all plan views | ViewPlan.GetUnderlayOrientation
|
||||
ViewPlan.SetUnderlayOrientation |
|
||||
View Range | PLAN_VIEW_RANGE | Valid for all plan views | ViewPlan.GetViewRange
|
||||
ViewPlan.SetViewRange |
|
||||
Orientation | PLAN_VIEW_NORTH | Valid for all plan views | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) | Valid values are 0 (Project North), 1 (True North)
|
||||
System Color Schemes | VIEW_SCHEMA_SETTING_FOR_SYSTEM_TEMPLATE | Valid for all plan views except for ceiling | No API access at the time (Revit 2020) |
|
||||
Depth Clipping | VIEW_BACK_CLIPPING | Valid for all plan views | Element.Parameter.AsInteger()
|
||||
Element.Parameter.Set(integer) | Valid values are 0 (No Clip), 1 (Clip With Line), 2 (Clip With No Line)
|
||||
Rendering Settings | VIEWER3D_RENDER_SETTINGS | Valid for all 3D views | View3D.GetRenderingSettings
|
||||
View3D.SetRenderingSettings |
|
||||
Visual Style | MODEL_GRAPHICS_STYLE_ANON_DRAFT | Valid for DraftingView | View.DisplayStyle property | Use also View.HasDisplayStyle()
|
||||
Fields | SCHEDULE_FIELDS_PARAM | Valid for all schedules | ViewSchedule.Definition.GetField
|
||||
ViewSchedule.Definition.AddField
|
||||
ViewSchedule.Definition.RemoveField |
|
||||
Filter | SCHEDULE_FILTER_PARAM | Valid for all schedules | ViewSchedule.Definition.GetFilter
|
||||
ViewSchedule.Definition.AddFilter
|
||||
ViewSchedule.Definition.RemoveFilter |
|
||||
Sorting/Grouping | SCHEDULE_GROUP_PARAM | Valid for all schedules | ViewSchedule.Definition.GetSortGroupField
|
||||
ViewSchedule.Definition.AddSortGroupField
|
||||
ViewSchedule.Definition.RemoveSortGroupField |
|
||||
Formatting | SCHEDULE_FORMAT_PARAM | Valid for all schedules | ViewSchedule.Definition.GetField().IsHidden
|
||||
ViewSchedule.Definition.GetField().ColumnHeading
|
||||
ViewSchedule.Definition.GetField().GetFormatOptions
|
||||
ViewSchedule.Definition.GetField().SetFormatOptions
|
||||
etc. |
|
||||
Appearance | SCHEDULE_SHEET_APPEARANCE_PARAM | Valid for all schedules | ViewSchedule.Definition.ShowTitle
|
||||
ViewSchedule.Definition.ShowHeaders
|
||||
etc. |
|
||||
| | | |
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,133 @@
|
||||
# Overview
|
||||
|
||||
# Overview
|
||||
|
||||
A project model can have several view types. In the API, there are three ways to classify views. The first way is by using the view element View.ViewType property. It returns an enumerated value indicating the view type. The following table lists all available view types.
|
||||
|
||||
**Table 44: Autodesk.Revit.DB.ViewType**
|
||||
|
||||
**Member Name** | **Description**
|
||||
---|---
|
||||
AreaPlan | Area view.
|
||||
CeilingPlan | Reflected ceiling plan view.
|
||||
ColumnSchedule | Coulmn schedule view.
|
||||
CostReport | Cost report view.
|
||||
Detail | Detail view.
|
||||
DraftingView | Drafting view.
|
||||
DrawingSheet | Drawing sheet view.
|
||||
Elevation | Elevation view.
|
||||
EngineeringPlan | Engineering view.
|
||||
FloorPlan | Floor plan view.
|
||||
Internal | Revit's internal view.
|
||||
Legend | Legend view.
|
||||
LoadsReport | Loads report view.
|
||||
PanelSchedule | Panel schedule view.
|
||||
PressureLossReport | Pressure Loss Report view.
|
||||
Rendering | Rendering view.
|
||||
Report | Report view.
|
||||
Schedule | Schedule view.
|
||||
Section | Cross section view.
|
||||
ThreeD | 3-D view.
|
||||
Undefined | Undefined/unspecified view.
|
||||
Walkthrough | Walkthrough view.
|
||||
|
||||
The second way to classify views is by the class type.
|
||||
|
||||
The following table lists the view types and the corresponding views in the Project browser.
|
||||
|
||||
**Table 45: Project Browser Views**
|
||||
|
||||
**Project Browser Views** | **View Type** | **Class Type**
|
||||
---|---|---
|
||||
Area Plans | ViewType.AreaPlan | Elements.ViewPlan
|
||||
Ceiling Plans | ViewType.CeilingPlan | Elements.ViewPlan
|
||||
Graphic Column Schedule | ViewType.ColumnSchedule | Elements.View
|
||||
Detail Views | ViewType.Detail | Elements.ViewSection
|
||||
Drafting Views | ViewType.DraftingView | Elements.ViewDrafting
|
||||
Sheets | ViewType.DrawingSheet | Elements.ViewSheet
|
||||
Elevations | ViewType.Elevation | Elements.ViewSection
|
||||
Structural Plans | ViewType.EngineeringPlan | Elements.ViewPlan
|
||||
Floor Plans | ViewType.FloorPlan | Elements.ViewPlan
|
||||
Legends | ViewType.Legend | Elements.View
|
||||
Reports (MEP engineering) | ViewType.LoadsReport | Elements.View
|
||||
Reports (MEP engineering) | ViewType.PanelSchedule | Elements.PanelScheduleView
|
||||
Reports (MEP engineering) | ViewType.PresureLossReport | Elements.View
|
||||
Renderings | ViewType.Rendering | Elements.ViewDrafting
|
||||
Reports | ViewType.Report | Elements.View
|
||||
Schedules/Quantities | ViewType.Schedule | Elements.ViewSchedule
|
||||
Sections | ViewType.Section | Elements.ViewSection
|
||||
3D Views | ViewType.ThreeD | Elements.View3D
|
||||
Walkthroughs | ViewType.Walkthrough | Elements.View3D
|
||||
|
||||
This example shows how to use the ViewType property of a view to determine the view's type.
|
||||
|
||||
**Code Region: Determining the View type**
|
||||
---
|
||||
|
||||
|
||||
public void GetViewType(Autodesk.Revit.DB.View view)
|
||||
{
|
||||
// Get the view type of the given view, and format the prompt string
|
||||
String prompt = "The view is ";
|
||||
|
||||
switch (view.ViewType)
|
||||
{
|
||||
case ViewType.AreaPlan:
|
||||
prompt += "an area view.";
|
||||
break;
|
||||
case ViewType.CeilingPlan:
|
||||
prompt += "a reflected ceiling plan view.";
|
||||
break;
|
||||
case ViewType.ColumnSchedule:
|
||||
prompt += "a column schedule view.";
|
||||
break;
|
||||
case ViewType.CostReport:
|
||||
prompt += "a cost report view.";
|
||||
break;
|
||||
case ViewType.Detail:
|
||||
prompt += "a detail view.";
|
||||
break;
|
||||
case ViewType.DraftingView:
|
||||
prompt += "a drafting view.";
|
||||
break;
|
||||
case ViewType.DrawingSheet:
|
||||
prompt += "a drawing sheet view.";
|
||||
break;
|
||||
case ViewType.Elevation:
|
||||
prompt += "an elevation view.";
|
||||
break;
|
||||
case ViewType.EngineeringPlan:
|
||||
prompt += "an engineering view.";
|
||||
break;
|
||||
case ViewType.FloorPlan:
|
||||
prompt += "a floor plan view.";
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Give the user some information
|
||||
TaskDialog.Show("Revit", prompt);
|
||||
}
|
||||
|
||||
The third way to classify views is using the ViewFamilyType class. Most view creation methods required the Id of a ViewFamilyType for the new view. The Id of the ViewFamilyType can be retrieved from the View.GetTypeId() method. The ViewFamilyType.ViewFamily property returns a ViewFamily enumeration which specifies the family of the ViewFamilyType and similar to the ViewType enum documented above. The following example shows how to get the ViewFamily from a View.
|
||||
|
||||
**Code Region: Determining view type from ViewFamilyType**
|
||||
---
|
||||
|
||||
|
||||
public ViewFamily GetViewFamily(Document doc, View view)
|
||||
{
|
||||
ViewFamily viewFamily = ViewFamily.Invalid;
|
||||
|
||||
ElementId viewTypeId = view.GetTypeId();
|
||||
if (viewTypeId.Value > 1) // some views may not have a ViewFamilyType
|
||||
{
|
||||
ViewFamilyType viewFamilyType = doc.GetElement(viewTypeId) as ViewFamilyType;
|
||||
viewFamily = viewFamilyType.ViewFamily;
|
||||
}
|
||||
|
||||
return viewFamily;
|
||||
}
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,89 @@
|
||||
# PanelScheduleView
|
||||
|
||||
# PanelScheduleView
|
||||
|
||||
PanelScheduleView represents a panel schedule which displays information about a panel, the circuits connected to the panel, and their corresponding loads.
|
||||
|
||||
You can create a schedule that lists the circuits connected to a panel, and displays information about each circuit such as location on the panel, circuit name and apparent loads. Panel schedules display four main information sections: a header, circuit table, a loads summary and a footer. A new Panel Schedule view for the selected panel is displayed in the drawing area, and panel schedules are added to the project browser under the Panel Schedules folder. A panel schedule shows the following data:
|
||||
|
||||
* Panel Name
|
||||
* Distribution System supported by the panel
|
||||
* Number of phases available from the panel
|
||||
* Number of wires specified for the distribution system assigned to this panel
|
||||
* Rating of the mains feeding the panel
|
||||
* Type of mounting (Surface or Recessed)
|
||||
* Type of case enclosing the panel
|
||||
* Room where the panel is installed
|
||||
* Name assigned to a load circuit
|
||||
* Rated trip current for a circuit breaker
|
||||
* Number of poles on the circuit breaker
|
||||
* Circuit number
|
||||
* Phases
|
||||
* Apparent load (VA) for each of the phases
|
||||
* Total apparent load for all three phases
|
||||
* Manufacturer
|
||||
* Notation of any changes made to the panel
|
||||
* Root Means Square amperage Additional circuit and panel information to display can be specified in the panel schedule templates, represented in the Revit API by the PanelScheduleTemplate class.
|
||||
|
||||
|
||||
|
||||
PanelScheduleView is derived from the TableView class as is ViewSchedule. Some of the common functionality between schedules and panel schedules can be found in the [Schedule Classes](Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_Schedule_Classes_html.html "Schedule views use several supporting classes.") topic.
|
||||
|
||||
## Browser Organization for panel schedules
|
||||
|
||||
Browser organization options are enabled for panel schedules. Users can organize panel schedules by some properties of panels.
|
||||
|
||||
The methods:
|
||||
|
||||
* BrowserOrganization.GetCurrentBrowserOrganizationForPanelSchedules()
|
||||
* BrowserOrganization.GetSortingParameterIdPath() allow access to the BrowserOrganization that applies to the Panel Schedules section of the project browser and provides access to the parameter Id path used to determine the sorting order of items in the browser.
|
||||
|
||||
|
||||
|
||||
### Panel schedule creation
|
||||
|
||||
There are two static overloads for creating a PanelScheduleView. One overload of PanelScheduleView.CreateInstanceView() only requires the document in which to create the panel schedule and the id of the electrical panel element associated with the schedule. This method uses the default panel schedule template to create the new view. The other overload takes the id of a specific PanelScheduleTemplate to use.
|
||||
|
||||
The following example creates a new panel schedule from a user-selected electrical panel using the default template and switches the active view to the new panel schedule view.
|
||||
|
||||
**Code Region: Create a panel schedule**
|
||||
---
|
||||
|
||||
|
||||
// Create a new panel schedule and switch to that view
|
||||
public void CreatePanelSchedule(UIDocument uiDocument)
|
||||
{
|
||||
Document doc = uiDocument.Document;
|
||||
|
||||
Reference selected = uiDocument.Selection.PickObject(ObjectType.Element, "Select an electrical panel");
|
||||
|
||||
Element panel = doc.GetElement(selected);
|
||||
|
||||
if (null != panel)
|
||||
{
|
||||
PanelScheduleView psv = null;
|
||||
|
||||
using (Transaction trans = new Transaction(doc, "Create a new panel schedule"))
|
||||
{
|
||||
trans.Start();
|
||||
psv = PanelScheduleView.CreateInstanceView(doc, panel.Id);
|
||||
trans.Commit();
|
||||
}
|
||||
if (null != psv)
|
||||
{
|
||||
uiDocument.ActiveView = psv; // make new view the active view
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskDialog.Show("Revit", "Please select one electrical panel.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### Working with panel schedules
|
||||
|
||||
After a schedule is created, you may want to modify it. Several methods are helpful for moving data in the schedule. To move data around, use PanelScheduleView.GetCellsBySlotNumber() to get the range of cells for a specified slot number. PanelScheduleView.MoveSlotTo() moves the circuits in the source slot to the specific slot. Prior to moving the circuits, call PanelScheduleView.CanMoveSlotTo() to ensure the move is allowable.
|
||||
|
||||
If the moving circuit is in a group, all circuits in the group will be moved accordingly. The IsSlotGrouped() method will check if the slot is in a group. This method returns 0 if the slot is not in a group. If it is in a group, the returned value with be the group number (a value greater than 0).
|
||||
|
||||
**Parent page:** [TableView](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_html.html)
|
||||
@@ -0,0 +1,136 @@
|
||||
# Schedule Classes
|
||||
|
||||
# Schedule Classes
|
||||
|
||||
Schedule views use several supporting classes.
|
||||
|
||||
TableView is a class that represents a view that shows a table and it is the base class for ViewSchedule and PanelScheduleView. It has an associated TableData class which contains one or more sections. For ViewSchedule, there is only one header and one body section.
|
||||
|
||||
The TableSectionData class represents a contiguous set of cells arranged in rows and columns. For a ViewSchedule the cell contents of TableSectionData are generated from the ScheduleDefinition and parameters. Also, for ViewSchedules, while the header section has read/write permissions, the body section is read-only.
|
||||
|
||||
### Working with data in a schedule
|
||||
|
||||
The actual data for a table is contained in the TableData class. Although the TableData object cannot be obtained directly from the TableView class, both child classes have a GetTableData() method. For ViewSchedule, this method returns a TableData object. For a PanelScheduleView, GetTableData() returns a PanelScheduleData object, which derives from the TableData base class. The TableData class holds most of the data that describe the style of the rows, columns, and cells in a table. PanelScheduleData provides additional methods related specifically to panel schedules.
|
||||
|
||||
### Working with rows, columns and cells
|
||||
|
||||
Data in a table is broken down into sections. To work with the rows, columns and cells of the TableData, it is necessary to get the a TableSectionData object. TableData.GetSectionData() can be called with either an integer to the requested section data, or using the SectionType (i.e. Header or Body).
|
||||
|
||||
The TableSectionData class can be used to insert or remove rows or columns, format cells, and to get details of the cells that make up that section of the schedule, such as the cell type (i.e. Text or Graphic) or the cell's category id.
|
||||
|
||||
In the following example, a new row is added to the header section of the schedule and the text is set for the newly created cell. Note that the first row of the header section defaults to the title when created with the UI.
|
||||
|
||||
**Code Region: Inserting a row**
|
||||
---
|
||||
|
||||
|
||||
public void CreateSubtitle(ViewSchedule schedule)
|
||||
{
|
||||
TableData colTableData = schedule.GetTableData();
|
||||
|
||||
TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
|
||||
tsd.InsertRow(tsd.FirstRowNumber + 1);
|
||||
tsd.SetCellText(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber, "Schedule of column top and base levels with offsets");
|
||||
}
|
||||
|
||||
Also note, in the code example above, it uses the properties FirstRowNumber and FirstColumnNumber. In some sections the row or column numbers might start with 0, or they might start with 1. These properties should always be used in place of a hardcoded 0 or 1.
|
||||
|
||||
In the following example, a new single-category schedule is created with a custom header section.
|
||||
|
||||
**Code Region: Customizing the header section**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateSingleCategoryScheduleWithSimpleHeaderSection(Document doc)
|
||||
{
|
||||
using (Transaction t = new Transaction(doc, "Create single-category with custom headers"))
|
||||
{
|
||||
// Build schedule
|
||||
t.Start();
|
||||
ViewSchedule vs = ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Windows));
|
||||
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_HEIGHT));
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_WIDTH));
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.ALL_MODEL_MARK));
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.ALL_MODEL_COST));
|
||||
|
||||
doc.Regenerate();
|
||||
|
||||
// Get header section
|
||||
TableSectionData data = vs.GetTableData().GetSectionData(SectionType.Header);
|
||||
|
||||
int rowNumber = data.LastRowNumber;
|
||||
int columnNumber = data.LastColumnNumber;
|
||||
|
||||
// Get the overall width of the table so that the new columns can be resized properly
|
||||
double tableWidth = data.GetColumnWidth(columnNumber);
|
||||
|
||||
data.InsertColumn(columnNumber);
|
||||
data.InsertColumn(columnNumber);
|
||||
|
||||
// Refresh data to be sure that schedule is ready for text insertion
|
||||
vs.RefreshData();
|
||||
|
||||
//Set text to the first header cell
|
||||
data.SetCellText(rowNumber, data.FirstColumnNumber, "Special Window Schedule Text");
|
||||
|
||||
// Set width of first column
|
||||
data.SetColumnWidth(data.FirstColumnNumber, tableWidth / 3.0);
|
||||
|
||||
//Set a different parameter to the second cell - the project name
|
||||
data.SetCellParamIdAndCategoryId(rowNumber, data.FirstRowNumber + 1, new ElementId(BuiltInParameter.PROJECT_NAME),
|
||||
new ElementId(BuiltInCategory.OST_ProjectInformation));
|
||||
data.SetColumnWidth(data.FirstColumnNumber + 1, tableWidth / 3.0);
|
||||
|
||||
//Set the third column as the schedule view name - use the special category for schedule parameters for this
|
||||
data.SetCellParamIdAndCategoryId(rowNumber, data.LastColumnNumber, new ElementId(BuiltInParameter.VIEW_NAME),
|
||||
new ElementId(BuiltInCategory.OST_ScheduleViewParamGroup));
|
||||
data.SetColumnWidth(data.LastColumnNumber, tableWidth / 3.0);
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRegularFieldToSchedule(ViewSchedule schedule, ElementId paramId)
|
||||
{
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
|
||||
// Find a matching SchedulableField
|
||||
SchedulableField schedulableField =
|
||||
definition.GetSchedulableFields().FirstOrDefault<SchedulableField>(sf => sf.ParameterId == paramId);
|
||||
|
||||
if (schedulableField != null)
|
||||
{
|
||||
// Add the found field
|
||||
definition.AddField(schedulableField);
|
||||
}
|
||||
}
|
||||
|
||||
The style of rows, columns, or individual cells can be customized for schedules. This includes the ability to set the border line style for all four sides of cells, as well as cell color and text appearance (i.e. color, font, size). For regular schedules, this can only be done in the header section of the table.
|
||||
|
||||
In the example below, the font of the subtitle of a ViewSchedule (assumed to be the second row of the header section) is set to bold and the font size is set to 10.
|
||||
|
||||
**Code Region: Formatting cells**
|
||||
---
|
||||
|
||||
|
||||
public void FormatSubtitle(ViewSchedule colSchedule)
|
||||
{
|
||||
TableData colTableData = colSchedule.GetTableData();
|
||||
|
||||
TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
|
||||
// Subtitle is second row, first column
|
||||
if (tsd.AllowOverrideCellStyle(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber))
|
||||
{
|
||||
TableCellStyle tcs = new TableCellStyle();
|
||||
TableCellStyleOverrideOptions options = new TableCellStyleOverrideOptions();
|
||||
options.FontSize = true;
|
||||
options.Bold = true;
|
||||
tcs.SetCellStyleOverrideOptions(options);
|
||||
tcs.IsFontBold = true;
|
||||
tcs.TextSize = 10;
|
||||
tsd.SetCellStyle(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber, tcs);
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [TableView](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_html.html)
|
||||
@@ -0,0 +1,118 @@
|
||||
# Creating a Schedule
|
||||
|
||||
# Creating a Schedule
|
||||
|
||||
The ViewSchedule class has several methods for creating new schedules depending on the type of schedule. All of the methods have a Document parameter that is the document to which the new schedule or schedule-like view will be added. The newly created schedule views will appear under the Schedules/Quantities node in the Project Browser.
|
||||
|
||||
A standard single-category or multi-category schedule can be created with the static ViewSchedule.CreateSchedule() method.
|
||||
|
||||
**Code Region: Create a single-category schedule with 2 fields**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateSingleCategorySchedule(Document doc)
|
||||
{
|
||||
using (Transaction t = new Transaction(doc, "Create single-category"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
// Create schedule
|
||||
ViewSchedule vs = ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Windows));
|
||||
|
||||
doc.Regenerate();
|
||||
|
||||
// Add fields to the schedule
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_HEIGHT));
|
||||
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_WIDTH));
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single parameter field to the schedule
|
||||
/// </summary>
|
||||
public static void AddRegularFieldToSchedule(ViewSchedule schedule, ElementId paramId)
|
||||
{
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
|
||||
// Find a matching SchedulableField
|
||||
SchedulableField schedulableField =
|
||||
definition.GetSchedulableFields().FirstOrDefault<SchedulableField>(sf => sf.ParameterId == paramId);
|
||||
|
||||
if (schedulableField != null)
|
||||
{
|
||||
// Add the found field
|
||||
definition.AddField(schedulableField);
|
||||
}
|
||||
}
|
||||
|
||||
The second parameters the ID of the category whose elements will be included in the schedule, or InvalidElementId for a multi-category schedule.
|
||||
|
||||
A second CreateSchedule() method can be used to create an area schedule and takes an additional parameter that is the ID of an area scheme for the schedule.
|
||||
|
||||
**Code Region: Creating an area schedule**
|
||||
---
|
||||
|
||||
|
||||
public void CreateAreaSchedule(Document doc)
|
||||
{
|
||||
FilteredElementCollector collector = new FilteredElementCollector(doc);
|
||||
collector.OfCategory(BuiltInCategory.OST_AreaSchemes);
|
||||
//Get first ElementId of AreaScheme.
|
||||
ElementId areaSchemeId = collector.FirstElementId();
|
||||
if (areaSchemeId != null && areaSchemeId != ElementId.InvalidElementId)
|
||||
{
|
||||
// If you want to create an area schedule, you must use CreateSchedule method with three arguments.
|
||||
// The value of the second argument must be ElementId of BuiltInCategory.OST_Areas category
|
||||
// and the value of third argument must be ElementId of an AreaScheme.
|
||||
ViewSchedule areaSchedule = Autodesk.Revit.DB.ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Areas), areaSchemeId);
|
||||
}
|
||||
}
|
||||
|
||||
A key schedule displays abstract "key" elements that can be used to populate parameters of ordinary model elements and can be created with the static ViewSchedule.CreateKeySchedule() method whose second parameter is the ID of the category of elements with which the schedule's keys will be associated.A material takeoff is a schedule that displays information about the materials that make up elements in the model. Unlike regular schedules where each row (before grouping) represents a single element, each row in a material takeoff represents a single <element, material> pair. The ViewSchedule.CreateMaterialTakeoff() method has the same parameters as the ViewSchedule.CreateSchedule() method and allows for both single- and multi-category material takeoff schedules.
|
||||
|
||||
View lists, sheet lists, and keynote legends are associated with a designated category and therefore their creation methods do take a category ID as a parameter. A view list is a schedule of views in the project. It is a schedule of the Views category and is created using ViewSchedule.CreateViewList().
|
||||
|
||||
A sheet list is a schedule of sheets in the project. It is a schedule of the Sheets category and is created using the ViewSchedule.CreateSheetList() method.
|
||||
|
||||
A keynote legend is a schedule of the Keynote Tags category and is created using ViewSchedule.CreateKeynoteLegend().
|
||||
|
||||
Revision schedules are added to titleblock families and become visible as part of titleblocks on sheets. The ViewSchedule.CreateRevisionSchedule() method will throw an exception if the document passed in is not a titleblock family.
|
||||
|
||||
A note block is a schedule of the Generic Annotations category that shows elements of a single family rather than all elements in a category.
|
||||
|
||||
The second parameter is the ID of the family whose elements will be included in the schedule.
|
||||
|
||||
**Code Region: Creating a note block schedule**
|
||||
---
|
||||
|
||||
|
||||
public void CreateNoteBlock(Document doc)
|
||||
{
|
||||
using (Transaction transaction = new Transaction(doc, "Creating Note Block"))
|
||||
{
|
||||
//Get first ElementId of a Note Block family.
|
||||
ICollection<ElementId> noteblockFamilies = ViewSchedule.GetValidFamiliesForNoteBlock(doc);
|
||||
ElementId symbolId = noteblockFamilies.First<ElementId>();
|
||||
ViewSchedule noteBlockSchedule = null;
|
||||
if (!symbolId.Equals(ElementId.InvalidElementId))
|
||||
{
|
||||
transaction.Start();
|
||||
|
||||
//Create a note-block view schedule.
|
||||
noteBlockSchedule = ViewSchedule.CreateNoteBlock(doc, symbolId);
|
||||
}
|
||||
|
||||
if (null != noteBlockSchedule)
|
||||
{
|
||||
transaction.Commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [ViewSchedule](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_ViewSchedule_html.html)
|
||||
@@ -0,0 +1,408 @@
|
||||
# Working with ViewSchedule
|
||||
|
||||
# Working with ViewSchedule
|
||||
|
||||
The ScheduleDefinition class helps define the ViewSchedule.
|
||||
|
||||
The ScheduleDefinition class contains various settings related to the contents of a schedule view, including:
|
||||
|
||||
* The schedule's category and other basic properties that determine the type of schedule.
|
||||
* A set of fields that become the columns of the schedule.
|
||||
* Sorting and grouping criteria.
|
||||
* Filters that restrict the set of elements visible in the schedule.
|
||||
* Settings to control visibility of the title, headers, and grid lines.
|
||||
|
||||
|
||||
|
||||
Most schedules contain a single ScheduleDefinition which is retrieved via the ViewSchedule.Definition property. In Revit, schedules of certain categories can contain an "embedded schedule" containing elements associated with the elements in the primary schedule, for example a room schedule showing the elements inside each room or a duct system schedule showing the elements associated with each system. An embedded schedule has its own category, fields, filters, etc. Those settings are stored in a second ScheduleDefinition object. When present, the embedded ScheduleDefinition is obtained from the ScheduleDefinition.EmbeddedDefinition property.
|
||||
|
||||
## Adding Fields
|
||||
|
||||
Once a ViewSchedule is created, fields can be added. The ScheduleDefinition.GetSchedulableFields() method will return a list of SchedulableField objects representing the non-calculated fields that may be included in the schedule. A new field can be added from a SchedulableField object or using a ScheduleFieldType. The following table describes the options available from the ScheduleFieldType enumeration.
|
||||
|
||||
**Member name** | **Description**
|
||||
---|---
|
||||
Instance | An instance parameter of the scheduled elements. All shared parameters also use this type, regardless of whether they are instance or type parameters.
|
||||
ElementType | A type parameter of the scheduled elements.
|
||||
Count | The number of elements appearing on the schedule row.
|
||||
ViewBased | A specialized type of field used for a few parameters whose displayed values can change based on the settings of the view:
|
||||
|
||||
* ROOM_AREA and ROOM_PERIMETER in room and space schedules.
|
||||
* PROJECT_REVISION_REVISION_NUM in revision schedules.
|
||||
* KEYNOTE_NUMBER in keynote legends that are numbered by sheet.
|
||||
|
||||
|
||||
Formula | A formula calculated from the values of other fields in the schedule.
|
||||
Percentage | A value indicating what percent of the total of another field each element represents.
|
||||
Room | A parameter of the room that a scheduled element belongs to.
|
||||
FromRoom | A parameter of the room on the "from" side of a door or window.
|
||||
ToRoom | A parameter of the room on the "to" side of a door or window.
|
||||
ProjectInfo | A parameter of the Project Info element in the project that the scheduled element belongs to, which may be a linked file. Only allowed in schedules that include elements from linked files.
|
||||
Material | In a material takeoff, a parameter of one of the materials of a scheduled element.
|
||||
MaterialQuantity | In a material takeoff, a value representing how a particular material is used within a scheduled element. The parameter ID can be MATERIAL_AREA, MATERIAL_VOLUME, or MATERIAL_ASPAINT.
|
||||
RevitLinkInstance | A parameter of the RevitLinkInstance that an element in a linked file belongs to. Currently RVT_LINK_INSTANCE_NAME is the only supported parameter. Only allowed in schedules that include elements from linked files.
|
||||
RevitLinkType | A parameter of the RevitLinkType that an element in a linked file belongs to. Currently RVT_LINK_FILE_NAME_WITHOUT_EXT is the only supported parameter. Only allowed in schedules that include elements from linked files.
|
||||
StructuralMaterial | A parameter of the structural material of a scheduled element.
|
||||
Space | A parameter of the space that a scheduled element belongs to.
|
||||
|
||||
Using one of the ScheduleDefinition.AddField() methods will add the field to the end of the field list. To place a new field in a specific location in the field list, use one of the ScheduleDefinition.InsertField() methods. Fields can also be ordered after the fact using ScheduleDefinition.SetFieldOrder().
|
||||
|
||||
### Scheduling Revision Clouds
|
||||
|
||||
Revision clouds and the view name and sheet info for revision clouds can be scheduled using the following values for the `Autodesk.Revit.DB.ScheduleFieldType` enum.
|
||||
|
||||
* Revision - Represents the parameter of the revision element that the scheduled revision cloud element belongs to.
|
||||
* Views - Represents the parameter of the primary view owning an annotation element (e.g., Revision Cloud).
|
||||
* Sheets - Represents the parameter of the sheet view owning an annotation element (e.g., Revision Cloud).
|
||||
|
||||
|
||||
|
||||
The following is a simple example showing how to add fields to a view if they are not already in the view schedule.
|
||||
|
||||
**Code Region: Adding fields to a schedule**
|
||||
---
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add fields to view schedule.
|
||||
/// </summary>
|
||||
/// <param name="schedules">List of view schedule.</param>
|
||||
public void AddFieldToSchedule(List<ViewSchedule> schedules)
|
||||
{
|
||||
IList<SchedulableField> schedulableFields = null;
|
||||
|
||||
foreach (ViewSchedule vs in schedules)
|
||||
{
|
||||
//Get all schedulable fields from view schedule definition.
|
||||
schedulableFields = vs.Definition.GetSchedulableFields();
|
||||
|
||||
foreach (SchedulableField sf in schedulableFields)
|
||||
{
|
||||
bool fieldAlreadyAdded = false;
|
||||
//Get all schedule field ids
|
||||
IList<ScheduleFieldId> ids = vs.Definition.GetFieldOrder();
|
||||
foreach (ScheduleFieldId id in ids)
|
||||
{
|
||||
//If the GetSchedulableField() method of gotten schedule field returns same schedulable field,
|
||||
// it means the field is already added to the view schedule.
|
||||
if (vs.Definition.GetField(id).GetSchedulableField() == sf)
|
||||
{
|
||||
fieldAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//If schedulable field doesn't exist in view schedule, add it.
|
||||
if (fieldAlreadyAdded == false)
|
||||
{
|
||||
vs.Definition.AddField(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The ScheduleField class represents a single field in a ScheduleDefinition's list of fields. Each (non-hidden) field becomes a column in the schedule.
|
||||
|
||||
Most commonly, a field represents an instance or type parameter of elements appearing in the schedule. Some fields represent parameters of other related elements, like the room to which a scheduled element belongs. Fields can also represent data calculated from other fields in the schedule, specifically Formula and Percentage fields.
|
||||
|
||||
The ScheduleField class has properties to control column headings, both the text as well as the orientation. Column width and horizontal alignment of text within a column can also be defined.
|
||||
|
||||
The ScheduleField.IsHidden property can be used to hide a field. A hidden field is not displayed in the schedule, but it can be used for filtering, sorting, grouping, and conditional formatting and can be referenced by Formula and Percentage fields.
|
||||
|
||||
### DisplayType
|
||||
|
||||
The ScheduleField has a DisplayType property which indicates the display type for the field. Possible values are:
|
||||
|
||||
* **Standard** \- Nothing is displayed if the values of the elements are different, otherwise, the common value will be displayed.
|
||||
* **Totals** -Calculates and displays the total value.
|
||||
* **MinMax** \- Calculates and displays the minimum and maximum values.
|
||||
* **Min** -Calculates and displays the maximum value.
|
||||
* **Max** \- Calculates and displays the minimum value. The ScheduleField.CanDisplayMinMax() method indicates whether this field can display minimum and maximum values. In a non-itemized schedule, values for the non-Standard display types are displayed in regular rows when multiple elements appear on the same row.
|
||||
|
||||
|
||||
|
||||
## Style and Formatting of Fields
|
||||
|
||||
ScheduleField.GetStyle() and ScheduleField.SetStyle() use the TableCellStyle class to work with the style of fields in a schedule. Using SetStyle(), various attributes of the field can be set, including the line style for the border of the cell as well as the text font, color and size.
|
||||
|
||||
ScheduleField.SetFormatOptions() and ScheduleField.GetFormatOptions() use the FormatOptions class to work with the formatting of a field's data. The FormatOptions class contains settings that control how to format numbers with units as strings. It contains those settings that are typically chosen by an end user in the Format dialog and stored in the document.
|
||||
|
||||
In the following example, all length fields in a ViewSchedule are formatted to display in feet and fractional inches.
|
||||
|
||||
**Code Region: Formatting a field**
|
||||
---
|
||||
|
||||
|
||||
// format length units to display in feet and inches format
|
||||
public void FormatLengthFields(ViewSchedule schedule)
|
||||
{
|
||||
int nFields = schedule.Definition.GetFieldCount();
|
||||
for (int n = 0; n < nFields; n++)
|
||||
{
|
||||
ScheduleField field = schedule.Definition.GetField(n);
|
||||
if (field.GetSpecTypeId() == SpecTypeId.Length)
|
||||
{
|
||||
FormatOptions formatOpts = new FormatOptions();
|
||||
formatOpts.UseDefault = false;
|
||||
formatOpts.SetUnitTypeId(UnitTypeId.FeetFractionalInches);
|
||||
field.SetFormatOptions(formatOpts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The example below applies both formatting and style overrides to a given field.
|
||||
|
||||
**Code Region: Apply formatting and style overrides to field**
|
||||
---
|
||||
|
||||
|
||||
public static void ApplyFormattingToField(ViewSchedule schedule, int fieldIndex)
|
||||
{
|
||||
// Get the field.
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
ScheduleField field = definition.GetField(fieldIndex);
|
||||
|
||||
// Build unit formatting for the field.
|
||||
FormatOptions options = field.GetFormatOptions();
|
||||
options.UseDefault = false;
|
||||
options.SetUnitTypeId(UnitTypeId.SquareInches);
|
||||
options.SetSymbolTypeId(SymbolTypeId.InCaret2);
|
||||
|
||||
// Build style overrides for the field
|
||||
// Use override options to indicate fields that are overridden and apply changes
|
||||
TableCellStyle style = field.GetStyle();
|
||||
TableCellStyleOverrideOptions overrideOptions = style.GetCellStyleOverrideOptions();
|
||||
overrideOptions.BackgroundColor = true;
|
||||
style.BackgroundColor = new Color(0x00, 0x00, 0xFF);
|
||||
overrideOptions.FontColor = true;
|
||||
style.TextColor = new Color(0xFF, 0xFF, 0xFF);
|
||||
overrideOptions.Italics = true;
|
||||
style.IsFontItalic = true;
|
||||
|
||||
style.SetCellStyleOverrideOptions(overrideOptions);
|
||||
|
||||
double width = field.GridColumnWidth;
|
||||
|
||||
using (Transaction t = new Transaction(schedule.Document, "Set style etc"))
|
||||
{
|
||||
t.Start();
|
||||
field.SetStyle(style);
|
||||
field.SetFormatOptions(options);
|
||||
// Change column width (affects width in grid and on sheet) - units are in Revit length units - ft.
|
||||
field.GridColumnWidth = width + 0.5;
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
### Title and Headers
|
||||
|
||||
Display of the schedule title and/or headers is optional. Whether the title or headers are shown can be controlled with the ScheduleDefinition properties ShowTitle and ShowHeaders.
|
||||
|
||||
### Grouping and Sorting in Schedules
|
||||
|
||||
A schedule may be sorted or grouped by one or more of the schedule's fields. Several methods can be used to control grouping and sorting of fields. The ScheduleSortGroupField class represents one of the fields that the schedule is sorted or grouped by. Sorting and grouping are related operations. In either case, elements appearing in the schedule are sorted based on their values for the field by which the schedule is sorted/grouped, which automatically causes elements with identical values to be grouped together. By enabling extra header, footer, or blank rows, visual separation between groups can be achieved.
|
||||
|
||||
If the ScheduleDefinition.IsItemized property is false, elements having the same values for all of the fields used for sorting/grouping will be combined onto the same row. Otherwise the schedule displays each element on a separate row.
|
||||
|
||||
A schedule can be sorted or grouped by data that is not displayed in the schedule by marking the field used for sorting/grouping as hidden using the ScheduleField.IsHidden property.
|
||||
|
||||
**Code Region: Add grouping/sorting to schedule**
|
||||
---
|
||||
|
||||
|
||||
public static void AddGroupingToSchedule(ViewSchedule schedule, BuiltInParameter paramEnum, bool withTotalsAndDecoration, ScheduleSortOrder order)
|
||||
{
|
||||
// Find field
|
||||
ScheduleField field = FindScheduleField(schedule, paramEnum);
|
||||
|
||||
if (field == null)
|
||||
throw new Exception("Unable to find field.");
|
||||
|
||||
// Build sort/group field.
|
||||
ScheduleSortGroupField sortGroupField = new ScheduleSortGroupField(field.FieldId, order);
|
||||
if (withTotalsAndDecoration)
|
||||
{
|
||||
sortGroupField.ShowFooter = true;
|
||||
sortGroupField.ShowFooterTitle = true;
|
||||
sortGroupField.ShowFooterCount = true;
|
||||
sortGroupField.ShowHeader = true;
|
||||
sortGroupField.ShowBlankLine = true;
|
||||
}
|
||||
|
||||
// Add the sort/group field
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
|
||||
using (Transaction t = new Transaction(schedule.Document, "Add sort/group field"))
|
||||
{
|
||||
t.Start();
|
||||
definition.AddSortGroupField(sortGroupField);
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static ScheduleField FindScheduleField(ViewSchedule schedule, BuiltInParameter paramEnum)
|
||||
{
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
ScheduleField foundField = null;
|
||||
ElementId paramId = new ElementId(paramEnum);
|
||||
|
||||
foreach (ScheduleFieldId fieldId in definition.GetFieldOrder())
|
||||
{
|
||||
foundField = definition.GetField(fieldId);
|
||||
if (foundField.ParameterId == paramId)
|
||||
{
|
||||
return foundField;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Headers can also be grouped. ViewSchedule.GroupHeaders() method can be used to specify which rows and columns to include in a grouping of the header section. The last parameter is a string for the caption of the grouped rows and columns.
|
||||
|
||||
In the following example, columns are grouped for a newly created single-category schedule.
|
||||
|
||||
**Code Region: Grouping headers**
|
||||
---
|
||||
|
||||
|
||||
public static void CreateSingleCategoryScheduleWithGroupedColumnHeaders(Document doc)
|
||||
{
|
||||
using (Transaction t = new Transaction(doc, "Create single-category with grouped column headers"))
|
||||
{
|
||||
// Build the schedule
|
||||
t.Start();
|
||||
ViewSchedule vs = ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Windows));
|
||||
|
||||
AddRegularField(vs, new ElementId(BuiltInParameter.WINDOW_HEIGHT));
|
||||
AddRegularField(vs, new ElementId(BuiltInParameter.WINDOW_WIDTH));
|
||||
AddRegularField(vs, new ElementId(BuiltInParameter.ALL_MODEL_MARK));
|
||||
AddRegularField(vs, new ElementId(BuiltInParameter.ALL_MODEL_COST));
|
||||
|
||||
doc.Regenerate();
|
||||
|
||||
// Group the headers in the body section using ViewSchedule methods
|
||||
vs.GroupHeaders(0, 0, 0, 1, "Size");
|
||||
vs.GroupHeaders(0, 2, 0, 3, "Other");
|
||||
vs.GroupHeaders(0, 0, 0, 3, "All");
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRegularField(ViewSchedule schedule, ElementId paramId)
|
||||
{
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
|
||||
// Find a matching SchedulableField
|
||||
SchedulableField schedulableField =
|
||||
definition.GetSchedulableFields().FirstOrDefault<SchedulableField>(sf => sf.ParameterId == paramId);
|
||||
|
||||
if (schedulableField != null)
|
||||
{
|
||||
// Add the found field
|
||||
definition.AddField(schedulableField);
|
||||
}
|
||||
}
|
||||
|
||||
### Filtering
|
||||
|
||||
A ScheduleFilter can be used to filter the elements that will be displayed in a schedule. A filter is a condition that must be satisfied for an element to appear in the schedule. All filters must be satisfied for an element to appear in the schedule.
|
||||
|
||||
A schedule can be filtered by data that is not displayed in the schedule by marking the field used for filtering as hidden using the ScheduleField.IsHidden property.
|
||||
|
||||
**Code Region: Add filter to schedule**
|
||||
---
|
||||
|
||||
|
||||
public static void AddFilterToSchedule(ViewSchedule schedule, ElementId levelId)
|
||||
{
|
||||
// Find level field
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
|
||||
ScheduleField levelField = FindField(schedule, BuiltInParameter.ROOM_LEVEL_ID);
|
||||
|
||||
// Add filter
|
||||
using (Transaction t = new Transaction(schedule.Document, "Add filter"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
// If field not present, add it
|
||||
if (levelField == null)
|
||||
{
|
||||
levelField = definition.AddField(ScheduleFieldType.Instance, new ElementId(BuiltInParameter.ROOM_LEVEL_ID));
|
||||
}
|
||||
|
||||
// Set field to hidden
|
||||
levelField.IsHidden = true;
|
||||
ScheduleFilter filter = new ScheduleFilter(levelField.FieldId, ScheduleFilterType.Equal, levelId);
|
||||
definition.AddFilter(filter);
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an existing ScheduleField matching the given parameter
|
||||
/// </summary>
|
||||
/// <param name="schedule"></param>
|
||||
/// <param name="paramEnum"></param>
|
||||
/// <returns></returns>
|
||||
public static ScheduleField FindField(ViewSchedule schedule, BuiltInParameter paramEnum)
|
||||
{
|
||||
ScheduleDefinition definition = schedule.Definition;
|
||||
ScheduleField foundField = null;
|
||||
ElementId paramId = new ElementId(paramEnum);
|
||||
|
||||
foreach (ScheduleFieldId fieldId in definition.GetFieldOrder())
|
||||
{
|
||||
foundField = definition.GetField(fieldId);
|
||||
if (foundField.ParameterId == paramId)
|
||||
{
|
||||
return foundField;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
### Multiple Value Formatting
|
||||
|
||||
The `ScheduleField` class has properties which allow customization of the multiple value indication per field:
|
||||
|
||||
* ScheduleField.MultipleValuesDisplayType
|
||||
* ScheduleField.MultipleValuesText - The text to be used when a field has multiple values.
|
||||
* ScheduleField.MultipleValuesCustomText - The text to be used when a field has multiple values and the display type is set to ScheduleFieldMultip leValuesDisplayType.Custom.
|
||||
|
||||
|
||||
|
||||
The Enum `ScheduleFieldMultipleValuesDisplayType` defines how the schedule field's multiple value indication is displayed (using the project setting, a custom text, or a predefined text "<varies>").
|
||||
|
||||
### Working with Schedule Data
|
||||
|
||||
The following example shows how to determine the list of elements in a schedule.
|
||||
|
||||
**Code Region: Get a schedule's contents**
|
||||
---
|
||||
|
||||
|
||||
public static void GetScheduleContents(ViewSchedule viewSchedule)
|
||||
{
|
||||
// Collect types displayed in the schedule
|
||||
FilteredElementCollector typeCollector = new FilteredElementCollector(viewSchedule.Document, viewSchedule.Id);
|
||||
typeCollector.WhereElementIsElementType();
|
||||
|
||||
int numberOfTypes = typeCollector.Count();
|
||||
|
||||
// Collect instances displayed in the schedule
|
||||
FilteredElementCollector instCollector = new FilteredElementCollector(viewSchedule.Document, viewSchedule.Id);
|
||||
instCollector.WhereElementIsNotElementType();
|
||||
|
||||
int numberOfInstances = instCollector.Count();
|
||||
|
||||
TaskDialog.Show("Elements in schedule", String.Format("Types {0} instances {1}", numberOfTypes, numberOfInstances));
|
||||
}
|
||||
|
||||
To work with the actual data in the schedule, the ViewSchedule.GetTableData() returns a TableData object that holds most of the data that describe the style and contents of the rows, columns, and cells in a table. More information can be found under [TableView](../../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_html.html).
|
||||
|
||||
**Parent page:** [ViewSchedule](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_ViewSchedule_html.html)
|
||||
@@ -0,0 +1,66 @@
|
||||
# ViewSchedule
|
||||
|
||||
# ViewSchedule
|
||||
|
||||
A schedule is a tabular representation of data. A typical schedule shows all elements of a category (doors, rooms, etc.) with each row representing an element and each column representing a parameter.
|
||||
|
||||
The ViewSchedule class represents schedules and other schedule-like views, including single-category and multi-category schedules, key schedules, material takeoffs, view lists, sheet lists, keynote legends, revision schedules, and note blocks.
|
||||
|
||||
The ViewSchedule.Export() method will export the schedule data to a text file.
|
||||
|
||||
TableData.ZoomLevel allows the user to set the zoom level of a schedule in a tabular view. This setting will not change the size of text, rows, or columns in a sheet view. Additionally, the setting is temporary and only applies to the current session.
|
||||
|
||||
## Placing Schedules on Sheets
|
||||
|
||||
The static ScheduleSheetInstance.Create() method creates an instance of a schedule on a sheet. It requires the ID of the sheet where the schedule will be placed, the ID of the schedule view, and the XYZ location on the sheet where the schedule will be placed. The ScheduleSheetInstance object has properties to access the ID of the "primary" schedule that generates this ScheduleSheetInstance, the rotation of the schedule on the sheet, the location on the sheet where the schedule is placed (in sheet coordinates), as well as a flag that identifies if the ScheduleSheetInstance is a revision schedule in a titleblock family.
|
||||
|
||||
The `GetScheduleHeightsOnSheet` method returns the height of the column headers, row heights, and schedule title.
|
||||
|
||||
## Striped rows
|
||||
|
||||
These properties provide access to read or set if a given schedule is using a striped row display, and whether that display will be used on a sheet that displays this schedule:
|
||||
|
||||
* ViewSchedule.HasStripedRows
|
||||
* ViewSchedule.UseStripedRowsOnSheets
|
||||
|
||||
|
||||
|
||||
These methods get and set the color applied to the indicated part of the pattern for a schedule with striped rows:
|
||||
|
||||
* ViewSchedule.GetStripedRowsColor()
|
||||
* ViewSchedule.SetStripedRowsColor()
|
||||
|
||||
|
||||
|
||||
## Row Height
|
||||
|
||||
`ViewSchedule.RowHeightOverride` allows users to define the override that is applied to the row height. `ViewSchedule.RowHeight` Allows users to define the schedule body rows height. The property is applied only for when the schedule is placed on sheet as a ScheduleSheetInstance. The new enum:
|
||||
|
||||
`Autodesk.Revit.DB.RowHeightOverrideOptions` describes the options for overriding schedule body row heights. It has the following values
|
||||
|
||||
* None - No override would be applied for the row height.
|
||||
* All - Override row height for any body rows in the schedule.
|
||||
* ImageRows - Override row height for body rows containing images in the schedule.
|
||||
|
||||
|
||||
|
||||
## Frozen header
|
||||
|
||||
`ViewSchedule.IsHeaderFrozen` provides access to read or set if the header is frozen on a given schedule.
|
||||
|
||||
## Split Schedules
|
||||
|
||||
Schedules can be split, and the resulting segments can be split, merged, and deleted. An overload of `ScheduleSheetInstance.Create` exists to place a schedule segment on a sheet.
|
||||
|
||||
## Filtering By Sheet
|
||||
|
||||
With the `ScheduleDefinition.IsFilteredBySheet` property, you can define if the `ScheduleSheetInstance` will list only the elements visible in the viewports on that sheet.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Creating a Schedule](ViewSchedule/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_ViewSchedule_Creating_a_Schedule_html.html)
|
||||
* [Working with ViewSchedule](ViewSchedule/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_ViewSchedule_Working_with_ViewSchedule_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [TableView](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_html.html)
|
||||
@@ -0,0 +1,17 @@
|
||||
# TableView
|
||||
|
||||
# TableView
|
||||
|
||||
This class represents a view that shows a table of data.
|
||||
|
||||
TableView is the base class for ViewSchedule and PanelScheduleView.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Schedule Classes](TableView/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_Schedule_Classes_html.html)
|
||||
* [ViewSchedule](TableView/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_ViewSchedule_html.html)
|
||||
* [PanelScheduleView](TableView/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_PanelScheduleView_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,234 @@
|
||||
# View3D
|
||||
|
||||
# View3D
|
||||
|
||||
View3D is a freely-oriented three-dimensional view.
|
||||
|
||||
There are two kinds of 3D views, perspective and isometric, also referred to as orthographic in the Revit user interface. The difference is based on the projection ray relationship. The View3D.IsPerspective property indicates whether a 3D view is perspective or isometric.
|
||||
|
||||
### Perspective view
|
||||
|
||||
The following picture illustrates how a perspective view is created.
|
||||
|
||||
**Figure 96: Perspective projection**
|
||||
|
||||
* The straight projection rays pass through each point in the model and intersect the projection plane to form the projection contents.
|
||||
* To facilitate the transformation from the world coordinate onto the view plane, the viewing coordinate system is based on the viewer.
|
||||
* Its origin, represented by the View.Origin property, is the viewer position.
|
||||
* The viewer's world coordinates are retrieved using the ViewOrientation3D.EyePosition property (retrieved from View3D.GetOrientation()). Therefore, in 3D views, View.Origin is always equal to the corresponding ViewOrientation3D.EyePosition.
|
||||
* As described in the diagram above, the _viewing_ coordinate system is determined as follows:
|
||||
* The X-axis is determined by View.RightDirection.
|
||||
* The Y-axis is determined by View.UpDirection.
|
||||
* The Z-axis is determined by View.ViewDirection.
|
||||
* The view direction is from the target point to the viewer in the 3D space, and from the screen to the viewer in the screen space.
|
||||
|
||||
|
||||
|
||||
The static method View3D.CreatePerspective() method can be used to create new perspective views. The viewFamilyTypeId parameter needs to be a three dimensional ViewType.
|
||||
|
||||
The following code sample illustrates how to create a perspective 3D view.
|
||||
|
||||
**Code Region: Creating a Perspective 3D view**
|
||||
---
|
||||
|
||||
|
||||
public void CreatePerspective(Document document)
|
||||
{
|
||||
// Find a 3D view type
|
||||
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
|
||||
let type = elem as ViewFamilyType
|
||||
where type.ViewFamily == ViewFamily.ThreeDimensional
|
||||
select type;
|
||||
// Create a new Perspective View3D
|
||||
View3D view3D = View3D.CreatePerspective(document, viewFamilyTypes.First().Id);
|
||||
if (null != view3D)
|
||||
{
|
||||
// By default, the 3D view uses a default orientation.
|
||||
// Change the orientation by creating and setting a ViewOrientation3D
|
||||
XYZ eye = new XYZ(0, -100, 10);
|
||||
XYZ up = new XYZ(0, 0, 1);
|
||||
XYZ forward = new XYZ(0, 1, 0);
|
||||
view3D.SetOrientation(new ViewOrientation3D(eye, up, forward));
|
||||
|
||||
// turn off the far clip plane with standard parameter API
|
||||
Parameter farClip = view3D.LookupParameter("Far Clip Active");
|
||||
farClip.Set(0);
|
||||
}
|
||||
}
|
||||
|
||||
The perspective view crop box is part of a pyramid with the apex at the viewer position. It is the geometry between the two parallel clip planes. The crop box bounds the portion of the model that is clipped out and projected onto the view plane.
|
||||
|
||||
* The crop box is represented by the View.CropBox property, which returns a BoundingBoxXYZ object.
|
||||
* The CropBox.Min and CropBox.Max points are marked in the previous picture. Note that the CropBox.Min point in a perspective view is generated by projecting the crop box front clip plane onto the back clip plane.
|
||||
|
||||
|
||||
|
||||
Crop box coordinates are based on the viewing coordinate system. Use Transform.OfPoint() to transform CropBox.Min and CropBox.Max to the world coordinate system. For more detail about Transform, refer to [Geometry Helper Classes](../../../Revit_Geometric_Elements/Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html) in the [Geometry](../../../Revit_Geometric_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html) section.
|
||||
|
||||
The project plane plus the front and back clip plane are all plumb to the view direction. The line between CropBox.Max and CropBox.Min is parallel to the view direction. With these factors, the crop box geometry can be calculated.
|
||||
|
||||
**Figure 97: Perspective 3D view**
|
||||
|
||||
The previous picture shows the projection plane on screen after cropping. The crop region is the rectangle intersection of the projection plane and crop box.
|
||||
|
||||
* Geometry information is retrieved using the View.CropRegion property. This property returns a BoundingBoxUV instance.
|
||||
* The View.OutLine.Max property points to the upper right corner.
|
||||
* The View.OutLine.Min property points to the lower left corner.
|
||||
* Like the crop box, the crop region coordinates are based on the viewing coordinate system. The following expressions are equal.
|
||||
|
||||
|
||||
|
||||
|
||||
View.CropBox.Max.X(Y) / View.OutLine.Max.X(Y) == View.CropBox.Min.X(Y) / View.OutLine.Min.X(Y)
|
||||
|
||||
Since the size of an object's perspective projection varies inversely with the distance from that object to the center of the projection, scale is meaningless for perspective views. The perspective 3D view Scale property always returns zero.
|
||||
|
||||
#### Managing the camera target
|
||||
|
||||
The camera represents the direction that the viewer of the perspective view is looking. If the user or an API application adjusts the crop region to expose a wider field of view or an unsymmetrical field of view, the distortion of the perspective view can become too drastic. The camera target can be forced to the center of the viewing region by calling the View3D method RestCameraTarget() which positions the target at the center of the field of view. Before calling, check to see if the camera can be reset in this view with the method View3D.CanResetCameraTarget() which indicates whether the camera target may be reset. The main situation where a target cannot be reset is if the View3D is currently in Isometric projection. Attempting to reset the camera target in an isometric view will throw an Autodesk.Revit.Exceptions.InvalidOperationException.
|
||||
|
||||
### Isometric view
|
||||
|
||||
A new isometric view can be created with the static View3D.CreateIsometric() method.
|
||||
|
||||
**Figure 98: Parallel projection**
|
||||
|
||||
Isometric views are generated using parallel projection rays by projecting the model onto a plane that is normal to the rays. The viewing coordinate system is similar to the perspective view, but the crop box is a parallelepiped with faces that are parallel or normal to the projection rays. The View.CropBox property points to two diagonal corners whose coordinates are based on the viewing coordinate system.
|
||||
|
||||
**Figure 99: Scale the window on view plane to screen viewport**
|
||||
|
||||
The model is projected onto a view plane and then scaled onto the screen. The View.Scale property represents the ratio of actual model size to the view size. The related expressions are as follows:
|
||||
|
||||
|
||||
public void ViewScale(View view)
|
||||
{
|
||||
view.CropBox.Max.X(Y) / view.OutLine.Max.X(Y) == view.CropBox.Min.X(Y) / view.OutLine.Min.X(Y) == view.Scale;
|
||||
}
|
||||
|
||||
The viewFamilyTypeId parameter needs to be a three dimensional ViewType. Revit determines the following:
|
||||
|
||||
* Position of the viewer.
|
||||
* How to create the viewing coordinate system using the view direction.
|
||||
* How to create the crop box to crop the model.
|
||||
|
||||
|
||||
|
||||
Once the view is created, you can resize the crop box to view different portions of the model. You can also change the default orientation. The API does not support modifying the viewing coordinate system.
|
||||
|
||||
The following code sample illustrates how to create an isometric 3D view.
|
||||
|
||||
**Code Region: Creating an Isometric 3D view**
|
||||
---
|
||||
|
||||
|
||||
public void CreateIso(Document document)
|
||||
{
|
||||
// Find a 3D view type
|
||||
|
||||
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
|
||||
let type = elem as ViewFamilyType
|
||||
where type.ViewFamily == ViewFamily.ThreeDimensional
|
||||
select type;
|
||||
|
||||
// Create a new View3D
|
||||
View3D view3D = View3D.CreateIsometric(document, viewFamilyTypes.First().Id);
|
||||
if (null != view3D)
|
||||
{
|
||||
// By default, the 3D view uses a default orientation.
|
||||
// Change the orientation by creating and setting a ViewOrientation3D
|
||||
XYZ eye = new XYZ(10, 10, 10);
|
||||
XYZ up = new XYZ(0, 0, 1);
|
||||
XYZ forward = new XYZ(0, 1, 0);
|
||||
|
||||
ViewOrientation3D viewOrientation3D = new ViewOrientation3D(eye, up, forward);
|
||||
view3D.SetOrientation(viewOrientation3D);
|
||||
}
|
||||
}
|
||||
|
||||
### **Switching between isometric and perspective**
|
||||
|
||||
Most of the time a View3D can be toggled between Isometric and Perspective, provided that there are no view-specific elements in the view. The View3D class provides methods for toggling the view to and from Isometric and Perspective mode. Before toggling, use the CanToggleBetweenPerspectiveAndIsometric() method which indicates whether toggling is ok.
|
||||
|
||||
To toggle the view call one of the two View3D class methods: ToggleToPerspective() or ToggleToIsometric(). In the case that the view cannot be toggled (perhaps due to the presence of view specific elements in the view) either of these methods will throw Autodesk.Revit.Exceptions.InvalidOperationException.
|
||||
|
||||
### 3D Views SectionBox
|
||||
|
||||
Each view has a crop box. The crop box focuses on a portion of the model to project and show in the view. For 3D views, there is another box named section box.
|
||||
|
||||
* The section box determines which model portion appears in a 3D view.
|
||||
* The section box is used to clip the 3D model's visible portion.
|
||||
* The part outside the box is invisible even if it is in the crop box.
|
||||
* The section box is different from the crop box in that it can be rotated and moved with the model.
|
||||
|
||||
|
||||
|
||||
The section box is particularly useful for large models. For example, if you want to render a large building, use a section box. The section box limits the model portion used for calculation. To display the section box, in the 3D view Element Properties dialog box, select Section Box in the Extents section. You can also set it using the IsSectionBoxActive property. In the example below, if the active view is a 3D view, it sets whether the section box is active.
|
||||
|
||||
**Code Region: Showing/Hiding the Section Box**
|
||||
---
|
||||
|
||||
|
||||
private void ShowHideSectionBox(UIDocument document, bool active)
|
||||
{
|
||||
if (document.ActiveView is View3D)
|
||||
{
|
||||
View3D view3d = document.ActiveView as View3D;
|
||||
view3d.IsSectionBoxActive = active;
|
||||
}
|
||||
}
|
||||
|
||||
**Figure 100: Section box**
|
||||
|
||||
The View3D.GetSectionBox() and View3D.SetSectionBox() methods are used to get and change the box extents. In some cases, calling View3D.SetSectionBox() can have a side effect. Setting the property to certain values can change the box capacity and display it in the view. To avoid displaying the section box, set the IsSectionBoxActive property to false.
|
||||
|
||||
The following code sample illustrates how to change the extents of the section box.
|
||||
|
||||
**Code Region: Changing the extents of the section box**
|
||||
---
|
||||
|
||||
|
||||
private void ExpandSectionBox(View3D view)
|
||||
{
|
||||
// The original section box
|
||||
BoundingBoxXYZ sectionBox = view.GetSectionBox();
|
||||
|
||||
// Expand the section box (doubling in size in all directions while preserving the same center and orientation)
|
||||
Autodesk.Revit.DB.XYZ deltaXYZ = sectionBox.Max - sectionBox.Min;
|
||||
sectionBox.Max += deltaXYZ / 2;
|
||||
sectionBox.Min -= deltaXYZ / 2;
|
||||
|
||||
//After resetting the section box, it will be shown in the view.
|
||||
//It only works when the Section Box is active
|
||||
view.SetSectionBox(sectionBox);
|
||||
}
|
||||
|
||||
The coordinates of Max and Min points of BoundingBoxXYZ returned from the GetSectionBox() method are not in global coordinates. To convert the coordinates of Max and Min to global coordinates, you need to convert each point via the transform obtained from BoundingBoxXYZ.Transform property. **Code Region: Convert Max and Min to global coordinates**
|
||||
---
|
||||
|
||||
|
||||
private void ConvertMaxMinToGlobal(View3D view, out XYZ max, out XYZ min)
|
||||
{
|
||||
BoundingBoxXYZ sectionbox = view.GetSectionBox();
|
||||
Transform transform = sectionbox.Transform;
|
||||
max = transform.OfPoint(sectionbox.Max);
|
||||
min = transform.OfPoint(sectionbox.Min);
|
||||
}
|
||||
|
||||
#### View locking
|
||||
|
||||
The View3D class has methods and properties corresponding to the locking feature available in the Revit user interface.
|
||||
|
||||
The View3D.SaveOrientationAndLock() method will save the orientation and lock the view while View3D.RestoreOrientationAndLock() will restore the view's orientation and lock it. View3D.Unlock() will unlock the view if it is currently locked. The IsLocked property will return whether the 3D view is currently locked.
|
||||
|
||||
#### Grid Visibility
|
||||
|
||||
Grid visiility in 3D Views can be accessed with:
|
||||
|
||||
* View3D.GetLevelsThatShowGrids()
|
||||
* View3D.ShowGridsOnLevel(ElementId levelId)
|
||||
* View3D.HideGridsOnLevel(ElementId levelId)
|
||||
* View3D.ShowGridsOnLevels(ElementIdset levelIds)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,38 @@
|
||||
# ViewDrafting
|
||||
|
||||
# ViewDrafting
|
||||
|
||||
Views to create unassociated, view-specific details that are not part of the modeled design.
|
||||
|
||||
The drafting view is not associated with the model. It allows the user to create detail drawings that are not included in the model.
|
||||
|
||||
* In the drafting view, the user can create details in different view scales (coarse, fine, or medium).
|
||||
|
||||
* You can use 2D detailing tools, including:
|
||||
|
||||
* Detail lines
|
||||
* Detail regions
|
||||
* Detail components
|
||||
* Insulation
|
||||
|
|
||||
* Reference planes
|
||||
* Dimensions
|
||||
* Symbols
|
||||
* Text
|
||||
---|---
|
||||
|
||||
|
||||
|
||||
These tools are the same tools used to create a detail view.
|
||||
|
||||
* Drafting views do not display model elements.
|
||||
|
||||
|
||||
|
||||
Use the static ViewDrafting.Create() method to create a drafting view. Model elements are not displayed in the drafting view.
|
||||
|
||||
### ImageView
|
||||
|
||||
The ImageView class is derived from ViewDrafting. It can be used to create rendering views containing images imported from disk. Use the static ImageView.Create(Document, ImageTypeOptions) method to create new rendering views.
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,134 @@
|
||||
# ViewPlan
|
||||
|
||||
# ViewPlan
|
||||
|
||||
Plan views are level-based. There are three types of plan views: floor plan view, ceiling plan view, and area plan view.
|
||||
|
||||
## Creating plan view
|
||||
|
||||
* Generally the floor plan view is the default view opened in a new project.
|
||||
|
||||
* Most projects include at least one floor plan view and one ceiling plan view.
|
||||
|
||||
* Plan views are usually created after adding new levels to the project.
|
||||
|
||||
|
||||
|
||||
|
||||
Adding new levels using the API does not add plan views automatically. Use the static ViewPlan.Create() method to create new floor and ceiling plan views. Use the static ViewPlan.CreateAreaPlan() method to create a new area plan view.
|
||||
|
||||
**Code Region: Creating Plan Views**
|
||||
---
|
||||
|
||||
|
||||
public static ViewPlan ViewPlan.Create(Document document, ElementId viewFamilyTypeId, ElementId levelId);
|
||||
|
||||
public static ViewPlan ViewPlan.CreateAreaPlan(Document document, ElementId areaSchemeId, ElementId levelId);
|
||||
|
||||
The viewFamilyTypeId parameter in ViewPlan.Create() needs to be a FloorPlan, CeilingPlan, AreaPlan, or StructuralPlan ViewType. The levelId parameter represents the Id of the level element in the project to which the plan view is associated.
|
||||
|
||||
The following code creates a floor plan and a ceiling plan based on a certain level.
|
||||
|
||||
**Code Region: Creating a floor plan and ceiling plan**
|
||||
---
|
||||
|
||||
|
||||
private void CreateViewPlan(Autodesk.Revit.DB.Document document)
|
||||
{
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
IList<Element> viewFamilyTypes = collector.OfClass(typeof(ViewFamilyType)).ToElements();
|
||||
ElementId floorPlanId = ElementId.InvalidElementId;
|
||||
foreach (Element e in viewFamilyTypes)
|
||||
{
|
||||
ViewFamilyType v = e as ViewFamilyType;
|
||||
|
||||
if (v != null && v.ViewFamily == ViewFamily.FloorPlan)
|
||||
{
|
||||
floorPlanId = e.Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ElementId ceilingPlanId = ElementId.InvalidElementId;
|
||||
foreach (Element e in viewFamilyTypes)
|
||||
{
|
||||
if (e.Name == "Ceiling Plan")
|
||||
{
|
||||
ceilingPlanId = e.Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a Level and a Floor Plan based on it
|
||||
double elevation = 10.0;
|
||||
Level level1 = Level.Create(document, elevation);
|
||||
ViewPlan floorView = ViewPlan.Create(document, floorPlanId, level1.Id);
|
||||
|
||||
// Create another Level and a Ceiling Plan based on it
|
||||
elevation += 10.0;
|
||||
Level level2 = Level.Create(document, elevation);
|
||||
ViewPlan ceilingView = ViewPlan.Create(document, ceilingPlanId, level2.Id);
|
||||
}
|
||||
|
||||
## Plan view properties
|
||||
|
||||
After creating a new plan view, the Discipline for the view can be set using the Discipline parameter which is type ViewDiscipline. Options include Architectural, Structural, Mechanical, Electrical, Plumbing and Coordination.
|
||||
|
||||
For structural plan views, the view direction can be set to either Up or Down using the ViewFamilyType.PlanViewDirection property. Although it is a property of the ViewFamilyType class, an exception will be thrown if the property is accessed for views other than StructuralPlan views.
|
||||
|
||||
## View range
|
||||
|
||||
The view range for plan views can be retrieved via the ViewPlan.GetViewRange() method. The returned PlanViewRange object can be used to find the levels which a plane is relative to and the offset of each plane from that level. It is the same information that is available in the View Range dialog in the Revit user interface:
|
||||
|
||||
The following example shows how to get the top clip plane and the associated offset for a plan view
|
||||
|
||||
**Code Region: Getting information on the view range**
|
||||
---
|
||||
|
||||
|
||||
private void ViewRange(Document doc, View view)
|
||||
{
|
||||
if (view is ViewPlan)
|
||||
{
|
||||
ViewPlan viewPlan = view as ViewPlan;
|
||||
PlanViewRange viewRange = viewPlan.GetViewRange();
|
||||
|
||||
ElementId topClipPlane = viewRange.GetLevelId(PlanViewPlane.TopClipPlane);
|
||||
double dOffset = viewRange.GetOffset(PlanViewPlane.TopClipPlane);
|
||||
|
||||
if (topClipPlane.Value > 0)
|
||||
{
|
||||
Element levelAbove = doc.GetElement(topClipPlane);
|
||||
TaskDialog.Show(view.Name, "Top Clip Plane: " + levelAbove.Name + "\r\nTop Offset: " + dOffset + " ft");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Plan view underlay
|
||||
|
||||
The top and base levels of the underlay range can be retrieved and set from ViewPlan. Use GetUnderlayBaseLevel() and SetUnderlayBaseLevel() to access the base level for the underlay range. If the base level id is InvalidElementId then the underlay base level is not set and no elements will be displayed as underlay. When setting the base level for the underlay range, the elevation of the next highest level will be used to determine the top of the underlay range. If the level specified for the base level is the highest level, the underlay range will be unbounded and will consist of everything above the specified level.
|
||||
|
||||
Use GetUnderlayTopLevel() and SetUnderlayRange() to access the top level for the underlay range. If GetUnderlayTopLevel() returns InvalidElementId and the underlay base level is a valid level, then the underlay range is unbounded, and consists of everything above the underlay base level. To set the top level, you must use SetUnderlayRange() which takes ElementIds for both the base and top levels. This method will throw an exception if the elevation of the top level is not greater than the elevation of the base level.
|
||||
|
||||
Use the GetUnderlayOrientation() and SetUnderlayOrientation() methods to control how elements in the underlay are viewed. The UnderlayOrientation is either LookingDown (underlay elements are viewed as if looking down from above ) or LookingUp (underlay elements are viewed as if looking up from below).
|
||||
|
||||
The following code sets the underlay range if the current orientation is LookingDown and the top level Id is different than the new value. Then the orientation is changed to LookingUp.
|
||||
|
||||
**Code Region: Change the view underlay range**
|
||||
---
|
||||
|
||||
|
||||
private void ViewUnderlay(ViewPlan planView, ElementId topLevelId, ElementId baseLevelId)
|
||||
{
|
||||
if (planView.GetUnderlayOrientation() == UnderlayOrientation.LookingDown)
|
||||
{
|
||||
if (planView.GetUnderlayTopLevel() != topLevelId)
|
||||
{
|
||||
planView.SetUnderlayRange(baseLevelId, topLevelId);
|
||||
}
|
||||
|
||||
planView.SetUnderlayOrientation(UnderlayOrientation.LookingUp);
|
||||
}
|
||||
}
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,177 @@
|
||||
# ViewSection
|
||||
|
||||
# ViewSection
|
||||
|
||||
Represents section, detail, callout and elevation views, as well as reference callouts and reference sections.
|
||||
|
||||
The ViewSection class can be used to create section views, detail views, callout views, reference callouts and reference sections. It also represents elevation views.
|
||||
|
||||
### Section Views and Reference Sections
|
||||
|
||||
Section views cut through the model to expose the interior structure. The `ViewSection.CreateSection()` method creates the section view.
|
||||
|
||||
The viewFamilyTypeId parameter is the Id for the ViewFamilyType which will be used by the new ViewSection. The type needs to be a Section ViewFamily. The sectionBox parameter is the section view crop box. It provides the direction and extents which are required for the section view. Usually, another view's crop box is used as the parameter. You can also build a custom BoundingBoxXYZ instance to represent the direction and extents.
|
||||
|
||||
The following code shows how to create a section view. A bounding box for the section view is created at the center of a wall. The resulting section view will be located in the Sections (Building Section) node in the Project Browser. Note that the far clip distance will be equal to the difference of the z-coordinates of bounding box's min and max values on creation.
|
||||
|
||||
**Code Region: Creating a section view**
|
||||
---
|
||||
|
||||
|
||||
public void CreateSection(Wall wall)
|
||||
{
|
||||
Document document = wall.Document;
|
||||
// Find a section view type
|
||||
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
|
||||
let type = elem as ViewFamilyType
|
||||
where type.ViewFamily == ViewFamily.Section
|
||||
select type;
|
||||
|
||||
// Create a BoundingBoxXYZ instance centered on wall
|
||||
LocationCurve lc = wall.Location as LocationCurve;
|
||||
Transform curveTransform = lc.Curve.ComputeDerivatives(0.5, true);
|
||||
// using 0.5 and "true" (to specify that the parameter is normalized)
|
||||
// places the transform's origin at the center of the location curve)
|
||||
|
||||
XYZ origin = curveTransform.Origin; // mid-point of location curve
|
||||
XYZ viewDirection = curveTransform.BasisX.Normalize(); // tangent vector along the location curve
|
||||
XYZ normal = viewDirection.CrossProduct(XYZ.BasisZ).Normalize(); // location curve normal @ mid-point
|
||||
|
||||
Transform transform = Transform.Identity;
|
||||
transform.Origin = origin;
|
||||
transform.BasisX = normal;
|
||||
transform.BasisY = XYZ.BasisZ;
|
||||
|
||||
// can use this simplification because wall's "up" is vertical.
|
||||
// For a non-vertical situation (such as section through a sloped floor the surface normal would be needed)
|
||||
transform.BasisZ = normal.CrossProduct(XYZ.BasisZ);
|
||||
|
||||
BoundingBoxXYZ sectionBox = new BoundingBoxXYZ();
|
||||
sectionBox.Transform = transform;
|
||||
sectionBox.Min = new XYZ(-10,0,0);
|
||||
sectionBox.Max = new XYZ(10,12,5);
|
||||
// Min & Max X values (-10 & 10) define the section line length on each side of the wall
|
||||
// Max Y (12) is the height of the section box// Max Z (5) is the far clip offset
|
||||
|
||||
// Create a new view section.
|
||||
ViewSection viewSection = ViewSection.CreateSection(document, viewFamilyTypes.First().Id, sectionBox);
|
||||
}
|
||||
|
||||
Reference sections are sections that reference an existing view. Revit does not add a new view when you create a new reference section.
|
||||
|
||||
**Code Region: ViewSection.CreateReferenceSection()**
|
||||
---
|
||||
|
||||
|
||||
public ViewSection ViewSection.CreateReferenceSection(Document document, ElementId parentViewId, ElementId viewIdToReference, XYZ headPoint, XYZ tailPoint);
|
||||
|
||||
The parentViewId parameter is the Id of the view in which the new reference section marker will appear. Reference sections can be created in FloorPlan, CeilingPlan, StructuralPlan, Section, Elevation, Drafting, and Detail views. The viewIdToReference can be the Id of a Detail, Drafting or Section view. The ViewFamilyType of the referenced view will be used by the new reference section. The two XYZ points will determine the location of the section marker's head in the parent view.
|
||||
|
||||
#### Detail Views
|
||||
|
||||
A detail view is a view of the model that appears as a callout or section in other views. This type of view typically represents the model at finer scales of detail than in the parent view. It is used to add more information to specific parts of the model. The static ViewSection.CreateDetail() method is used to create a new detail ViewSection.
|
||||
|
||||
**Code Region: ViewSection.CreateDetail()**
|
||||
---
|
||||
|
||||
|
||||
public ViewSection ViewSection.CreateDetail(Document document, ElementId viewFamilyTypeId, BoundingBoxXYZ sectionBox);
|
||||
|
||||
The viewFamilyTypeId parameter is the Id for the ViewFamilyType which will be used by the new ViewSection. The type needs to be a Detail ViewFamily. Just as for a standard section view, the sectionBox parameter is the section view crop box. It provides the direction and extents which are required for the section view.
|
||||
|
||||
When a new detail ViewSection is added, it will appear in the Detail Views (Detail) node in the Project Browser.
|
||||
|
||||
#### Elevation Views
|
||||
|
||||
An elevation view is a cross-section of the model where level lines are displayed. An elevation view is represented by the ViewSection class. However, unlike the other types of section views, you cannot create elevation views using a static method on the ViewSection class. To create an elevation view, first create an elevation marker, then use the marker to generate the elevation view. The newly created elevation view will appear in the Elevations (Building Elevation) node in the Project Browser. It will be assigned a unique name.
|
||||
|
||||
The following example creates an elevation view based on the location of a beam.
|
||||
|
||||
**Code Region: Creating an Elevation View**
|
||||
---
|
||||
|
||||
|
||||
ViewSection CreateElevationView(Document document, FamilyInstance beam)
|
||||
{
|
||||
// Find an elevation view type
|
||||
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
|
||||
let type = elem as ViewFamilyType
|
||||
where type.ViewFamily == ViewFamily.Elevation
|
||||
select type;
|
||||
|
||||
LocationCurve lc = beam.Location as LocationCurve;
|
||||
XYZ xyz = lc.Curve.GetEndPoint(0);
|
||||
ElevationMarker marker = ElevationMarker.CreateElevationMarker(document, viewFamilyTypes.First().Id, xyz, 1);
|
||||
ViewSection elevationView = marker.CreateElevation(document, document.ActiveView.Id, 1);
|
||||
|
||||
return elevationView;
|
||||
}
|
||||
|
||||
The ElevationMarker.CreateElevation() method takes an id of a ViewPlan as a parameter. That is the ViewPlan in which the ElevationMarker is visible. The new elevation ViewSection will derive its extents and inherit settings from the ViewPlan. The last parameter is the index on the ElevationMarker where the new elevation view will be placed. The index on the ElevationMarker must be valid and unused. The view's direction is determined by the index.
|
||||
|
||||
#### Split Sections
|
||||
|
||||
These methods identify if a section view is split and return the offset for the specified split crop region:
|
||||
|
||||
* DBViewSection.IsSplitSection()
|
||||
* ViewCropRegionShapeManager.GetSplitRegionOffset()
|
||||
|
||||
|
||||
|
||||
#### Callouts and Reference Callouts
|
||||
|
||||
A callout shows part of another view at a larger scale. Callout views can be created using the static method ViewSection.CreateCallout(). Callouts can be created in FloorPlan, CeilingPlan, StructuralPlan, Section, Elevation, Drafting and Detail views. The resulting view will be either a ViewSection, ViewPlan or ViewDetail depending on the ViewFamilyType used and will appear in the corresponding node in the Project Browser.
|
||||
|
||||
* `View.GetCalloutParentId()` returns the ID of a view which this callout references, or InvalidElementId if there is not parent.
|
||||
* `View.IsCallout` identifies if the view is a callout view.
|
||||
|
||||
**Code Region: ViewSection.CreateCallout()**
|
||||
---
|
||||
|
||||
|
||||
public ViewSection ViewSection.CreateCallout(Document document,
|
||||
ElementId parentViewId,
|
||||
ElementId viewFamilyTypeId,
|
||||
XYZ point1,
|
||||
XYZ point2);
|
||||
|
||||
The parent view Id parameter can be the Id of any type of View on which callouts can be created. The point parameters determine the extents of the callout symbol in the parent view.A reference callout is a callout that refers to an existing view. When you add a reference callout, Revit does not create a view in the project. Instead, it creates a pointer to a specified, existing view. Multiple reference callouts can point to the same view.
|
||||
|
||||
**Code Region: ViewSection.CreateReferenceCallout()**
|
||||
---
|
||||
|
||||
|
||||
public ViewSection ViewSection.CreateReferenceCallout(Document document,
|
||||
ElementId parentViewId,
|
||||
ElementId viewIdToReference,
|
||||
XYZ point1,
|
||||
XYZ point2);
|
||||
|
||||
Creation of a reference callout is similar to creation of a callout. But rather than having the Id of the ViewFamilyType for the callout as a parameter, the CreateReferenceCallout() method takes the Id of the view to reference. The ViewFamilyType of the referenced view will be used by the new reference callout.
|
||||
|
||||
Only cropped views can be referenced, unless the referenced view is a Drafting view. Drafting views can always be referenced regardless of the parent view type. Elevation views can be referenced from Elevation and Drafting parent views. Section views can be referenced from Section and Drafting parent views. Detail views can be referenced from all parent views except for in FloorPlan, CeilingPlan and StructuralPlan parent views where only horizontally-oriented Detail views can be referenced. FloorPlan, CeilingPlan and StructuralPlan views can be referenced from FloorPlan, CeilingPlan and StructuralPlan parent views.
|
||||
|
||||
The following example creates a new callout using a Detail ViewFamilyType and then uses the new callout view to create a reference callout.
|
||||
|
||||
**Code Region: Creating a callout and reference callout**
|
||||
---
|
||||
|
||||
|
||||
public void CreateCalloutView(Document document, View parentView)
|
||||
{
|
||||
// Find a detail view type
|
||||
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
|
||||
let type = elem as ViewFamilyType
|
||||
where type.ViewFamily == ViewFamily.Detail
|
||||
select type;
|
||||
|
||||
ElementId viewFamilyTypeId = viewFamilyTypes.First().Id;
|
||||
XYZ point1 = new XYZ(2, 2, 2);
|
||||
XYZ point2 = new XYZ(30, 30, 30);
|
||||
ElementId parentViewId = parentView.Id; // a ViewPlan
|
||||
View view = ViewSection.CreateCallout(document, parentViewId, viewFamilyTypeId, point1, point2);
|
||||
|
||||
ViewSection.CreateReferenceCallout(document, parentViewId, view.Id, point1, point2);
|
||||
}
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,222 @@
|
||||
# ViewSheet
|
||||
|
||||
# ViewSheet
|
||||
|
||||
A sheet contains views and a title block. When creating a sheet view with the ViewSheet.Create() method, a title block family symbol Id is a required parameter for the method. A title block family symbol can be found using a FilteredElementCollector.
|
||||
|
||||
**Code Region: ViewSheet.Create()**
|
||||
---
|
||||
|
||||
|
||||
public static ViewSheet ViewSheet.Create(Document document, ElementId titleBlockTypeId);
|
||||
|
||||
The newly created sheet has no views. The Viewport.Create() method is used to add views. The Viewport class is used to add regular views to a view sheet, i.e. plan, elevation, drafting and three dimensional. To add schedules to a view, use ScheduleSheetInstance.Create() instead.
|
||||
|
||||
The `View.GetPlacementOnSheetStatus` method returns a `ViewPlacementOnSheetStatus` enum that describes if the view is placed on a sheet. Some views, such as schedules, can be partially placed on a sheet by divided them into segments and placing only some of those segments on a sheet.
|
||||
|
||||
The property `Viewport.LabelOffset` controls the two-dimensional label offset from left bottom corner of the viewport (as established with Rotation set to None) to the left end of the viewport label line. The property `Viewport.LabelLineLength` controls the length of the viewport label line in sheet space.
|
||||
|
||||
**Code Region: Add two views aligned at left corner**
|
||||
---
|
||||
|
||||
|
||||
public static void PlaceAlignedViewsAtLeftCorner(Document doc)
|
||||
{
|
||||
FilteredElementCollector fec = new FilteredElementCollector(doc);
|
||||
fec.OfClass(typeof(ViewPlan));
|
||||
var viewPlans = fec.Cast<ViewPlan>().Where<ViewPlan>(vp => !vp.IsTemplate && vp.ViewType == ViewType.CeilingPlan);
|
||||
|
||||
ViewPlan vp1 = viewPlans.ElementAt(0);
|
||||
ViewPlan vp2 = viewPlans.ElementAt(1);
|
||||
|
||||
using (Transaction t = new Transaction(doc, "Place on sheet"))
|
||||
{
|
||||
t.Start();
|
||||
|
||||
// Add two viewports distinct from one another
|
||||
ViewSheet vs = ViewSheet.Create(doc, ElementId.InvalidElementId);
|
||||
Viewport viewport1 = Viewport.Create(doc, vs.Id, vp1.Id, new XYZ(0, 0, 0));
|
||||
Viewport viewport2 = Viewport.Create(doc, vs.Id, vp2.Id, new XYZ(0, 5, 0));
|
||||
|
||||
doc.Regenerate();
|
||||
|
||||
// Calculate the necessary move vector to align the lower left corner
|
||||
Outline outline1 = viewport1.GetBoxOutline();
|
||||
Outline outline2 = viewport2.GetBoxOutline();
|
||||
XYZ boxCenter = viewport2.GetBoxCenter();
|
||||
XYZ vectorToCenter = boxCenter - outline2.MinimumPoint;
|
||||
XYZ newCenter = outline1.MinimumPoint + vectorToCenter;
|
||||
|
||||
// Move the viewport to the new location
|
||||
viewport2.SetBoxCenter(newCenter);
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
* The XYZ location parameter identifies where the added views are located. It points to the added view's center coordinate (measured in inches).
|
||||
* The coordinates, [0, 0], are relative to the sheet's lower left corner.
|
||||
|
||||
|
||||
|
||||
Viewports placed on sheets can have the associated view swapped for another view in the model by editing the `Viewport.ViewId` property. When this swap is done, the `Viewport.ViewportPositioning` property specifies how the viewport will be positioned on the sheet when swapped to another view by maintaining either the viewport center or the view origin.
|
||||
|
||||
Each sheet has a unique sheet number in the complete drawing set. The number is displayed before the sheet name in the Project Browser. It is convenient to use the sheet number in a view title to cross-reference the sheets in your drawing set. You can retrieve or modify the number using the SheetNumber property. The number must be unique; otherwise an exception is thrown when you set the number to a duplicate value.
|
||||
|
||||
The following example illustrates how to create and print a sheet view. Begin by finding an available title block in the document (using a filter in this case) and use it to create the sheet view. Next, add a 3D view. The view is placed with its lower left-hand corner at the center of the sheet. Finally, print the sheet by calling the View.Print() method.
|
||||
|
||||
**Code Region: Creating a sheet view**
|
||||
---
|
||||
|
||||
|
||||
private void CreateSheetView(Autodesk.Revit.DB.Document document, View3D view3D)
|
||||
{
|
||||
|
||||
// Get an available title block from document
|
||||
FilteredElementCollector collector = new FilteredElementCollector(document);
|
||||
collector.OfClass(typeof(FamilySymbol));
|
||||
collector.OfCategory(BuiltInCategory.OST_TitleBlocks);
|
||||
|
||||
FamilySymbol fs = collector.FirstElement() as FamilySymbol;
|
||||
if (fs != null)
|
||||
{
|
||||
using (Transaction t = new Transaction(document, "Create a new ViewSheet"))
|
||||
{
|
||||
t.Start();
|
||||
try
|
||||
{
|
||||
// Create a sheet view
|
||||
ViewSheet viewSheet = ViewSheet.Create(document, fs.Id);
|
||||
if (null == viewSheet)
|
||||
{
|
||||
throw new Exception("Failed to create new ViewSheet.");
|
||||
}
|
||||
|
||||
// Add passed in view onto the center of the sheet
|
||||
UV location = new UV((viewSheet.Outline.Max.U - viewSheet.Outline.Min.U) / 2,
|
||||
(viewSheet.Outline.Max.V - viewSheet.Outline.Min.V) / 2);
|
||||
|
||||
//viewSheet.AddView(view3D, location);
|
||||
Viewport.Create(document, viewSheet.Id, view3D.Id, new XYZ(location.U, location.V, 0));
|
||||
|
||||
// Print the sheet out
|
||||
if (viewSheet.CanBePrinted)
|
||||
{
|
||||
TaskDialog taskDialog = new TaskDialog("Revit");
|
||||
taskDialog.MainContent = "Print the sheet?";
|
||||
TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No;
|
||||
taskDialog.CommonButtons = buttons;
|
||||
TaskDialogResult result = taskDialog.Show();
|
||||
|
||||
if (result == TaskDialogResult.Yes)
|
||||
{
|
||||
viewSheet.Print();
|
||||
}
|
||||
}
|
||||
|
||||
t.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
t.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Note: You cannot add a sheet view to another sheet and you cannot add a view to more than one sheet; otherwise an argument exception occurs.
|
||||
|
||||
### Duplicating a sheet
|
||||
|
||||
When duplicating a sheet, the SheetDuplicateOption enum allows you to indicate what information should be copied when duplicating a sheet. Its values are:
|
||||
|
||||
* DuplicateEmptySheet - Only copies the title block.
|
||||
* DuplicateSheetWithDetailing - Copies the title block and details.
|
||||
* DuplicateSheetWithViewsOnly- Copies the title block, details, viewports and contained views. The newly created sheet will reference the newly duplicated views.
|
||||
* DuplicateSheetWithViewsAndDetailing - Copies the title block, details, and viewports. Duplicates the sheet's contained views with detailing. The newly created sheet will reference the newly duplicated views.
|
||||
* DuplicateSheetWithViewsAsDependent - Copies the title block, details, and viewports. Duplicates the sheet's contained views as dependent. The newly created sheet will reference the newly duplicated dependent views.
|
||||
|
||||
|
||||
|
||||
### Revisions on Sheets
|
||||
|
||||
The ViewSheet class has several methods for working with revision and revision clouds on sheets.
|
||||
|
||||
* **GetAllRevisionIds()** \- Gets the ordered array of Revisions which participate in the sheet's revision schedules.
|
||||
* **GetAdditionalRevisionIds()** \- Gets the Revisions that are additionally included in the sheet's revision schedules.
|
||||
* **SetAdditionalRevisionIds()** \- Sets the Revisions to additionally include in the sheet's revision schedules.
|
||||
* **GetCurrentRevision()** \- Returns the most recent numbered Revision shown on this ViewSheet.
|
||||
* **GetRevisionCloudNumberOnSheet()** \- Gets the Revision Number for a RevisionCloud on this sheet when the numbering in the project is by sheet.
|
||||
* **GetRevisionNumberOnSheet()** \- Gets the Revision Number for a particular Revision as it will appear on this sheet when the numbering in the project is by sheet. The Revisions are ordered according to the revision sequence in the project. Additionally included Revisions will always participate in the sheet's revision schedules. Normally a Revision is scheduled in the revision schedule because one of its associated RevisionClouds is present on the sheet.
|
||||
|
||||
|
||||
|
||||
The following code sample demonstrates how to add additional revisions to the sheet that match a given criteria.
|
||||
|
||||
**Code Region: Add additional revisions to sheet**
|
||||
---
|
||||
|
||||
|
||||
public static void AddAdditionalRevisionsToSheet(ViewSheet viewSheet, String toMatch)
|
||||
{
|
||||
Document doc = viewSheet.Document;
|
||||
|
||||
ICollection<ElementId> revisions = viewSheet.GetAdditionalRevisionIds();
|
||||
|
||||
// Find revisions whose description matches input string
|
||||
FilteredElementCollector collector = new FilteredElementCollector(doc);
|
||||
collector.OfCategory(BuiltInCategory.OST_Revisions);
|
||||
collector.WhereElementIsNotElementType();
|
||||
if (revisions.Count > 0)
|
||||
collector.Excluding(revisions);
|
||||
|
||||
// Check if revision should be added
|
||||
foreach (Element revision in collector)
|
||||
{
|
||||
Parameter descriptionParam = revision.GetParameter(ParameterTypeId.ProjectRevisionRevisionDescription);
|
||||
String description = descriptionParam.AsString();
|
||||
if (description.Contains(toMatch))
|
||||
revisions.Add(revision.Id);
|
||||
}
|
||||
|
||||
if (revisions.Count > 0)
|
||||
{
|
||||
// Apply the new list of revisions
|
||||
using (Transaction t = new Transaction(doc, "Add revisions to sheet"))
|
||||
{
|
||||
t.Start();
|
||||
viewSheet.SetAdditionalRevisionIds(revisions);
|
||||
t.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### Printer Setup
|
||||
|
||||
You may want to change the settings of the printer before printing a sheet. The API exposes the settings for the printer with the PrintManager class, and related Autodesk.Revit.DB classes:
|
||||
|
||||
**Class** | **Functionality**
|
||||
---|---
|
||||
Autodesk.Revit.DB.PrintManager | Represents the Print information in Print Dialog (File->Print) within the Revit UI.
|
||||
Autodesk.Revit.DB.PrintParameters | An object that contains settings used for printing the document.
|
||||
Autodesk.Revit.DB.PrintSetup | Represents the Print Setup (File->Print Setup...) within the Revit UI.
|
||||
Autodesk.Revit.DB.PaperSize | An object that represents a Paper Size of Print Setup within the Autodesk Revit project.
|
||||
Autodesk.Revit.DB.PaperSizeSet | A set that can contain any number of paper size objects.
|
||||
Autodesk.Revit.DB.PaperSource | An object that represents a Paper Source of Print Setup within the Autodesk Revit project.
|
||||
Autodesk.Revit.DB.PaperSourceSet | A set that can contain any number of paper source objects.
|
||||
Autodesk.Revit.DB.ViewSheetSetting | Represents the View/Sheet Set (File->Print) within the Revit UI.
|
||||
Autodesk.Revit.DB.PrintSetting | Represents the Print Setup (File->Print Setup...) within the Revit UI.
|
||||
|
||||
For an example of code that uses these objects, see the ViewPrinter sample application that is included with the Revit Platform SDK.
|
||||
|
||||
### Sheet Collections
|
||||
|
||||
The class `Autodesk.Revit.DB.SheetCollection` represents a sheet collection in Autodesk Revit.
|
||||
|
||||
* `Autodesk.Revit.DB.SheetCollection.Create(document, name)` Creates a new instance of sheet collection with a **specified name** and adds it to the document. Returns the newly created sheet collection element.
|
||||
* `Autodesk.Revit.DB.SheetCollection.Create(document)` Creates a new instance of sheet collection with an **auto-generated name** and adds it to the document. Returns the newly created sheet collection element.
|
||||
* `Autodesk.Revit.DB.ViewSheet.SheetCollectionId` represents the Id of the sheet collection that a sheet is associated with.
|
||||
|
||||
|
||||
|
||||
**Parent page:** [View Types](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
@@ -0,0 +1,19 @@
|
||||
# View Types
|
||||
|
||||
# View Types
|
||||
|
||||
Different types of Revit views are represented by different classes in the Revit API. See the following topics for more information on each type of view.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [Overview](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_Overview_html.html)
|
||||
* [View3D](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_View3D_html.html)
|
||||
* [ViewPlan](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_ViewPlan_html.html)
|
||||
* [ViewDrafting](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_ViewDrafting_html.html)
|
||||
* [ViewSection](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_ViewSection_html.html)
|
||||
* [ViewSheet](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_ViewSheet_html.html)
|
||||
* [TableView](View_Types/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_TableView_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Views](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_html.html)
|
||||
@@ -0,0 +1,27 @@
|
||||
# Views
|
||||
|
||||
# Views
|
||||
|
||||
Views are images produced from a Revit model with privileged access to the data stored in the documents. They can be graphics, such as plans, or text, such as schedules. Each project document has one or more different views. The last focused window is the active view.
|
||||
|
||||
The Autodesk.Revit.DB.View class is the base class for all view types in the Revit document. The Autodesk.Revit.UI.UIView class represents the window view in the Revit user interface.
|
||||
|
||||
In the following sections, you learn how views are generated, the types of views supported by Revit, the features for each view, as well as the functionality available for view windows in the user interface.
|
||||
|
||||
**Pages in this section**
|
||||
|
||||
* [About views](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_About_views_html.html)
|
||||
* [View Graphics](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Graphics_html.html)
|
||||
* [Displaying Graphics with DirectContext3D](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_Displaying_Graphics_with_DirectContext3D_html.html)
|
||||
* [View Types](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Types_html.html)
|
||||
* [Revisions](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_Revisions_html.html)
|
||||
* [View Filters](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Filters_html.html)
|
||||
* [View Cropping](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Cropping_html.html)
|
||||
* [Displaced Views](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_Displaced_Views_html.html)
|
||||
* [UIView](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_UIView_html.html)
|
||||
* [View Templates](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_View_Templates_html.html)
|
||||
* [Temporary Graphics](Views/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Views_Temporary_Graphics_html.html)
|
||||
|
||||
|
||||
|
||||
**Parent page:** [Basic Interaction with Revit Elements](../Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_html.html)
|
||||
Reference in New Issue
Block a user