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:
minsung
2026-04-14 17:33:42 +09:00
parent 3bd01e31c9
commit b4a8714793
370 changed files with 28908 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# Annotation Symbol
# Annotation Symbol
An annotation symbol is a symbol applied to a family to uniquely identify that family in a project.
**Figure 76: Annotation Symbol with two leaders**
### Create and Delete
Annotation symbols can be created using the following overload of the Creation.Document.NewFamilyInstance() method:
**Code Region 16-6: Create a new Annotation Symbol**
---
`public FamilyInstance NewFamilyInstance Method (XYZ origin, FamilySymbol symbol, View specView)`
The annotation symbol can be deleted using the Document.Delete() method.
### Add and Remove Leader
Add and remove leaders using the addLeader() and removeLeader() methods.
**Code Region 16-7: Using addLeader() and removeLeader()**
---
public void AddAndRemoveLeaders(AnnotationSymbol symbol)
{
// check if there are any leaders currently attached, and remove them
IList<Leader> leaders = symbol.GetLeaders();
if (leaders != null && leaders.Count > 0)
{
for (int i = leaders.Count; i > 0; i--)
{
symbol.removeLeader();
}
}
// add one new leader instead
symbol.addLeader();
}
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,148 @@
# Color Fill
# Color Fill
## Color Fill Legend
`Autodesk.Revit.DB.ColorFillLegend` supports creating, reading and modifying properties of color fill legend annotation elements in a particular view. The static method `ColorFillLegend.Create(document, viewId, categoryId, origin)` lets you to create a new color fill legend in a view.
## Color Fill Scheme
The color fill scheme definition includes:
* The category (such as Rooms)
* The parameter whose value will be used to color the elements (such as Name, Floor Finish, or Department)
* If the coloring will be done by range of values (such as at least 40SF' and less than 80SF') or by specific values (such as equal to 40SF')
* The list of `ColorFillSchemeEntry` items
Key members of `Autodesk.Revit.DB.ColorFillScheme` relating to these attributes are:
* CategoryId
* ParameterDefinition
* IsByRange
* AddEntry()/DeleteEntry()
* GetEntries()/SetEntries()
### Color Fills Schemes used by a view
A view can define one `ColorFillScheme` for spatial elements (rooms, zones, spaces, and areas), one for pipes, and one for ducts. You can get and set these schemes with
* View.GetColorFillSchemeId(categoryId)
* View.SetColorFillSchemeId(categoryId, schemeId)
## Color Fill Scheme Entries
The color fill scheme entry definition includes:
* The color
* The fill pattern
* The caption shown in the Color Fill Legend (such as 100 SF' or more)
* The parameter value that will apply to this entry
The `Autodesk.Revit.DB.ColorFillSchemeEntry` class provides all functionality needed to create, read, and modify these entries.
**Code Region: Creating a Color Fill Legend**
private void CreateColorFill(View v)
{
Document doc = v.Document;
ElementId roomCatId = new ElementId(BuiltInCategory.OST_Rooms);
using (Transaction t = new Transaction(v.Document, "Create Color Fill Legend"))
{
t.Start();
if (v.GetColorFillSchemeId(roomCatId) == ElementId.InvalidElementId)
{
v.SetColorFillSchemeId(
roomCatId,
new FilteredElementCollector(doc)
.OfClass(typeof(ColorFillScheme))
.Cast<ColorFillScheme>()
.First(q => q.CategoryId == roomCatId).Id);
}
ColorFillLegend.Create(v.Document, v.Id, roomCatId, XYZ.Zero);
t.Commit();
}
}
**Code Sample - Create and Apply a Color Fill Scheme**
private void NewColorScheme(View v)
{
Document doc = v.Document;
ColorFillScheme scheme = doc.GetElement(
v.GetColorFillSchemeId(
new ElementId(BuiltInCategory.OST_Rooms))) as ColorFillScheme;
using (Transaction t = new Transaction(doc, "New Color Scheme"))
{
t.Start();
ElementId newSchemeId = scheme.Duplicate("Color By Room Finish");
ColorFillScheme newScheme = doc.GetElement(newSchemeId) as ColorFillScheme;
newScheme.Title = "Room Finish";
newScheme.ParameterDefinition = new ElementId(BuiltInParameter.ROOM_FINISH_BASE);
v.SetColorFillSchemeId(new ElementId(BuiltInCategory.OST_Rooms), newSchemeId);
t.Commit();
}
}
**Code Sample - Add an entry to a ColorFillScheme**
private void AddColorFillSchemeEntry(ColorFillScheme scheme)
{
Document doc = scheme.Document;
ColorFillSchemeEntry entry = new ColorFillSchemeEntry(StorageType.String)
{
Color = new Color(25, 0, 0),
FillPatternId = new FilteredElementCollector(doc)
.OfClass(typeof(FillPatternElement))
.Cast<FillPatternElement>()
.First(a => a.GetFillPattern().IsSolidFill)
.Id
};
entry.SetStringValue("Tile");
using (Transaction t = new Transaction(doc, "Add Scheme Entry"))
{
t.Start();
scheme.AddEntry(entry);
t.Commit();
}
}
**Code Sample - Modify entries of a ColorFillScheme**
private void ModifyColorFillSchemeEntries(ColorFillScheme scheme)
{
Document doc = scheme.Document;
IList<ColorFillSchemeEntry> entries = scheme.GetEntries();
foreach (ColorFillSchemeEntry entry in entries)
{
entry.FillPatternId = new FilteredElementCollector(doc)
.OfClass(typeof(FillPatternElement))
.Cast<FillPatternElement>()
.First(a => a.Name == "Crosshatch")
.Id;
}
using (Transaction t = new Transaction(doc, "Modify entry"))
{
t.Start();
scheme.SetEntries(entries);
t.Commit();
}
}
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,26 @@
# Detail Curve
# Detail Curve
Detail curve is an important Detail component usually used in the detail or drafting view. Detail curves are accessible in the DetailCurve class and its derived classes.
DetailCurve is view-specific as are other annotation elements. However, there is no DetailCurve.View property. When creating a detail curve, you must compare the detail curve to the model curve view.
**Code Region 16-4: NewDetailCurve() and NewModelCurve()**
---
public DetailCurve NewDetailCurve(View, Curve)
{
}
public ModelCurve NewModelCurve(Curve, SketchPlane)
{
}
Generally only 2D views such as level view and elevation view are acceptable, otherwise an exception is thrown.
Except for view-related features, DetailCurve is very similar to ModelCurve. For more information about ModelCurve properties and usage, see [ModelCurve](../Sketching/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_ModelCurve_html.html) in the [Sketching](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_html.html) section.
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,265 @@
# Dimensions and Constraints
# Dimensions and Constraints
## Permanent dimensions and dimension related constraints
The Dimension class represents permanent dimensions and dimension-related constraint elements. Temporary dimensions created while editing an element in the UI are not accessible. Spot elevation and spot coordinate are represented by the SpotDimension class.
The following code sample illustrates, near the end, how to distinguish permanent dimensions from constraint elements.
**Code Region 16-1: Distinguishing permanent dimensions from constraints**
---
public void GetInfo_Dimension(Dimension dimension)
{
string message = "Dimension : ";
// Get Dimension name
message += "\nDimension name is : " + dimension.Name;
// Get Dimension Curve
Autodesk.Revit.DB.Curve curve = dimension.Curve;
if (curve != null && curve.IsBound)
{
// Get curve start point
message += "\nCurve start point:(" + curve.GetEndPoint(0).X + ", "
+ curve.GetEndPoint(0).Y + ", " + curve.GetEndPoint(0).Z + ")";
// Get curve end point
message += "; Curve end point:(" + curve.GetEndPoint(1).X + ", "
+ curve.GetEndPoint(1).Y + ", " + curve.GetEndPoint(1).Z + ")";
}
// Get Dimension type name
message += "\nDimension type name is : " + dimension.DimensionType.Name;
// Get Dimension view name
message += "\nDimension view name is : " + dimension.View.Name;
// Get Dimension reference count
message += "\nDimension references count is " + dimension.References.Size;
if ((int)BuiltInCategory.OST_Dimensions == dimension.Category.Id.Value)
{
message += "\nDimension is a permanent dimension.";
}
else if ((int)BuiltInCategory.OST_Constraints == dimension.Category.Id.Value)
{
message += "\nDimension is a constraint element.";
}
TaskDialog.Show("Revit",message);
}
### Dimensions
There are five kinds of permanent dimensions:
* Linear dimension
* Radial dimension
* Diameter Dimension
* Angular dimension
* Arc length dimension
**Figure 66: Permanent dimensions**
The BuiltInCategory for all permanent dimensions is OST_Dimensions. There is not an easy way to distinguish the four dimensions using the API.
Except for radial and diameter dimensions, every dimension has one dimension line. Dimension lines are available from the Dimension.Curve property which is always unbound. In other words, the dimension line does not have a start-point or end-point. Based on the previous picture:
* A Line object is returned for a linear dimension.
* An arc object is returned for a radial dimension or angular dimension.
* A radial dimension returns null.
* A diamter diimension returns null.
**Figure 67: Dimension references**
A dimension is created by selecting geometric references as the previous picture shows. Geometric references are represented as a Reference class in the API. The following dimension references are available from the References property. For more information about Reference, please see [Geometry Helper Classes](../Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html) in the [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html) section.
* Radial and diameter dimensions - One Reference object for the curve is returned.
* Angular and arc length dimensions - Two Reference objects are returned.
* Linear dimensions - Two or more Reference objects are returned. In the following picture, the linear dimension has five Reference objects.
Dimensions can be created with the methods
* `RadialDimension.Create()`
* `ArcLengthDimension.Create()`
* `LinearDimension.Create()`
**Figure 68: Linear dimension references**
Dimensions, like other Annotation Elements, are view-specific. They display only in the view where they are added. The Dimension.View property returns the specific view.
### Constraint Elements
Dimension objects with Category Constraints (BuitInCategory.OST_Constraints) represent two kinds of dimension-related constraints:
* Linear and radial dimension constraints
* Equality constraints
In the following picture, two kinds of locked constraints correspond to linear and radial dimension. In the application, they appear as padlocks with green dashed lines. (The green dashed line is available from the Dimension.Curve property.) Both linear and radial dimension constraints return two Reference objects from the Dimension.References property.
**Figure 69: Linear and Radial dimension constraints**
Constraint elements are not view-specific and can display in different views. Therefore, the View property always returns null. In the following picture, the constraint elements in the previous picture are also visible in the 3D view.
**Figure 70: Linear and Radial dimension constraints in 3D view**
Although equality constraints are based on dimensions, they are also represented by the Dimension class. There is no direct way to distinguish linear dimension constraints from equality constraints in the API using a category or DimensionType. Equality constraints return three or more References while linear dimension constraints return two or more References.
**Figure 71: Equality constraints**
Note: Not all constraint elements are represented by the Dimension class but all belong to a Constraints (OST_Constraints) category such as alignment constraint.
### Spot Dimensions
Spot coordinates and spot elevations are represented by the SpotDimension class and are distinguished by category. Like the permanent dimension, spot dimensions are view-specific. The type and category for each spot dimension are listed in the following table:
**Table 35: Spot dimension Type and Category**
**Type** | **Category**
---|---
Spot Coordinates | OST_SpotCoordinates
Spot Elevations | OST_SpotElevations
**Figure 72: SpotCoordinates and SpotElevations**
The SpotDimension Location can be downcast to LocationPoint so that the point coordinate that the spot dimension points to is available from the LocationPoint.Point property.
* SpotDimensions have no dimension curve so their Curve property always returns null.
* The SpotDimension References property returns one Reference representing the point or the edge referenced by the spot dimension.
* To control the text and tag display style, modify the SpotDimension and SpotDimensionType Parameters.
Information about the leader of a spot dimension is accessible with:
* SpotDimension.LeaderElbowPosition
* SpotDimension.LeaderHasElbow
### Comparison
The following table compares different kinds of dimensions and constraints in the API:
**Table 36: Dimension Category Comparison**
**_Dimension or Constraint_** | **_Dimension or Constraint_** | **_API Class_** | **_BuiltInCategory_** | **_Curve_** | **_Geometry Helper Classes_** | **_View_** | **_Location_**
---|---|---|---|---|---|---|---
Permanent Dimension | linear dimension | LinearDimension | OST_Dimensions | A Line | =2 | Specific view | null
Permanent Dimension | radial dimension | RadialDimension | OST_Dimensions | Null | 1 | Specific view | null
Permanent Dimension | diameter dimension | Dimension | OST_Dimensions | Null | 1 | Specific view | null
Permanent Dimension | angular dimension | Dimension | OST_Dimensions | An Arc | 2 | Specific view | null
Permanent Dimension | arc length dimension | ArcLengthDimension | OST_Dimensions | An Arc | 2 | Specific view | null
Dimension Constraint | linear dimension constraint | Dimension | OST_Constraints | An Arc | 2 | | null
Dimension Constraint | angular dimension | Dimension | OST_Constraints | An Arc | 2 | | null
Equality Constraint | Equality Constraint | Dimension | OST_Constraints | A Line | =3 | | null
### Create and Delete
The NewDimension() method is available in the Creation.Document class. This method can create a linear dimension only.
**Code Region 16-2: NewDimension()**
---
`public Dimension NewDimension (View view, Line line, ReferenceArray references)`
`public Dimension NewDimension (View view, Line line, ReferenceArray references, DimensionType dimensionType)`
Using the NewDimension() method input parameters, you can define the visible View, dimension line, and References (two or more). However, there is no easy way to distinguish a linear dimension DimensionType from other types. The overloaded NewDimension() method with the DimensionType parameter is rarely used.
The following code illustrates how to use the NewDimension() method to duplicate a dimension.
**Code Region 16-3: Duplicating a dimension with NewDimension()**
---
public void DuplicateDimension(Document document, Dimension dimension)
{
Line line = dimension.Curve as Line;
if (null != line)
{
Autodesk.Revit.DB.View view = dimension.View;
ReferenceArray references = dimension.References;
Dimension newDimension = document.Create.NewDimension(view, line, references);
}
}
Though only linear dimensions are created, you can delete all dimensions and constraints represented by Dimension and SpotDimension using the Document.Delete() method.
### Manipulating Dimension Text and Leader
Access to several attributes of the dimension are available with:
* DimensionType.Prefix
* DimensionType.Suffix
* Dimension.TextPosition
* Dimension.LeaderEndPosition
* Dimension.HasLeader
Dimension and DimensionSegment classes provide similar properties and methods for querying and adjusting the position of the text relative to the dimension curve.
Dimension.Origin returns the XYZ value of the midpoint of the dimension curve, with DimensionSegment.Origin will return the midpoint of the line that makes up the segment.
Determine if text position of a Dimension or DimensionSegment is adjustable by calling the method IsTextPositionAdjustable() which will indicate whether the text and leader positions may be set.
Query or modify the position of text or the leader (of a dimension or dimension segment) by using the properties TextPosition and LeaderEndPosition.
Reset the text to its default position on a dimension by calling the method ResetTextPosition().
Note: TextPosition and LeaderEndPosition are not necessarily applicable to all dimensions (e.g., spot dimensions, multi-segment dimensions using the equality constraint, when dimension style is ordinate). If these values are not applicable they will return Null and not allow setting a value.
**Code Region: Reposition dimension text**
---
// Moves all of the text in this dimension one unit in the Y direction
public bool DimensionTextReposition(Dimension dimToModify)
{
bool modified = false;
if (dimToModify == null)
return false;
// Check to see if we have a non-multisegment dimension and if text position is adjustable
if (dimToModify.NumberOfSegments == 0 && dimToModify.IsTextPositionAdjustable())
{
// Get the current text XYZ position
XYZ currentTextPosition = dimToModify.TextPosition;
// Calculate a new XYZ position by transforming the current text position
XYZ newTextPosition = Transform.CreateTranslation(new XYZ(0.0, 1.0, 0.0)).OfPoint(currentTextPosition);
// Set the new text position
dimToModify.TextPosition = newTextPosition;
modified = true;
}
else if (dimToModify.NumberOfSegments > 0)
{
foreach (DimensionSegment currentSegment in dimToModify.Segments)
{
if (currentSegment != null && currentSegment.IsTextPositionAdjustable())
{
modified = true;
// Get the current text XYZ position
XYZ currentTextPosition = currentSegment.TextPosition;
// Calculate a new XYZ position by transforming the current text position
XYZ newTextPosition = Transform.CreateTranslation(new XYZ(0, 1, 0)).OfPoint(currentTextPosition);
// Set the new text position for the segment's text
currentSegment.TextPosition = newTextPosition;
}
}
}
return modified;
}
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,95 @@
# Tags
# Tags
A tag is an annotation used to identify drawing elements. The API exposes the IndependentTag and RoomTag classes to cover most tags used in the Revit application. For more details about RoomTag, see [Rooms](../../Discipline_Specific_Functionality/Architecture/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Architecture_Rooms_html.html).
Note: The IndependentTag class represents the tag element in Revit and other specific tags such as keynote, beam system tag, electronic circuit symbol, and so on. In Revit internal code, the specific tags have corresponding classes derived from IndependentTag. As a result, specific features are not exposed by the API and cannot be created using IndependentTag.Create. They can be distinguished by the following categories:
**Table 37: Tag Name and Category**
**Tag Name** | **BuiltInCategory**
---|---
Keynote Tag | OST_KeynoteTags
Beam System Tag | OST_BeamSystemTags
Electronic Circuit Tag | OST_ElectricalCircuitTags
Span Direction Tag | OST_SpanDirectionSymbol
Path Reinforcement Span Tag | OST_PathReinSpanSymbol
Rebar System Span Tag | OST_IOSRebarSystemSpanSymbolCtrl
Every category in the family library has a pre-made tag. Some tags are automatically loaded with the default Revit application template, while others are loaded manually. The IndependentTag objects return different categories based on the host element if it is created using the By Category option. For example, the Wall and Floor IndependentTag are respectively OST_WallTags and OST_FloorTags.
The method Autodesk.Revit.DB.IndependentTag.HasTagText() allows users to determine if the IndependentTag object has a valid tag text.
If the tag is created using the Multi-Category or Material style, their categories are respectively OST_MultiCategoryTags and OST_MaterialTags.
Note: Note that IndependentTag.Create only works in the 2D view or in a locked 3D view, otherwise an exception is thrown. The following code is an example of IndependentTag creation. Run it when the level view is the active view.
Note: You can't change the text displayed in the IndependentTag directly. You need to change the parameter that is used to populate tag text in the Family Type for the Element that's being tagged. In the example below, that parameter is "Type Mark", although this setting can be changed in the Family Editor in the Revit UI.
The `LeadersPresentationMode` property specifies how leaders should be displayed on a tag. It has the following values:
* ShowAll
* HideAll
* ShowOnlyOne
* ShowSpecificLeaders
`IsLeaderVisible()` returns whether the leader that points to the specified reference is visible or not, and `SetIsLeaderVisible()` sets the visibility of the leader that points to the specified reference.
**Code Region 16-5: Creating an IndependentTag**
---
private IndependentTag CreateIndependentTag(Autodesk.Revit.DB.Document document, Reference reference)
{
// make sure active view is not a 3D view
Autodesk.Revit.DB.View view = document.ActiveView;
if (view is View3D)
return null;
// define tag mode and tag orientation for new tag
TagMode tagMode = TagMode.TM_ADDBY_CATEGORY;
TagOrientation tagorn = TagOrientation.Horizontal;
// Add the tag to the middle of the wall
Wall wall = document.GetElement(reference) as Wall;
if (wall == null)
return null;
LocationCurve wallLoc = wall.Location as LocationCurve;
XYZ wallStart = wallLoc.Curve.GetEndPoint(0);
XYZ wallEnd = wallLoc.Curve.GetEndPoint(1);
XYZ wallMid = wallLoc.Curve.Evaluate(0.5, true);
IndependentTag newTag = IndependentTag.Create(document, view.Id, reference, true, tagMode, tagorn, wallMid);
if (null == newTag)
{
throw new Exception("Create IndependentTag Failed.");
}
// newTag.TagText is read-only, so we change the Type Mark type parameter to
// set the tag text. The label parameter for the tag family determines
// what type parameter is used for the tag text.
WallType type = wall.WallType;
Parameter foundParameter = type.LookupParameter("Type Mark");
bool result = foundParameter.Set("Hello");
// set leader mode free
// otherwise leader end point move with elbow point
newTag.LeaderEndCondition = LeaderEndCondition.Free;
XYZ elbowPnt = wallMid + new XYZ(5.0, 5.0, 0.0);
newTag.SetLeaderElbow(reference, elbowPnt);
XYZ headerPnt = wallMid + new XYZ(10.0, 10.0, 0.0);
newTag.TagHeadPosition = headerPnt;
return newTag;
}
**Figure 74: Create IndependentTag using sample code**
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,156 @@
# Text
# Text
Text and associated leaders can be accessed from the TextNote class.
A TextNote can have plain text or formatted text. The overloaded TextNote.Create() method provides options for creating unwrapped and line-wrapping text note elements. The width for the area of the text content can be specified on creation, but is restricted by a minimum and maximum width that is based on properties of the text and its type. The overloaded methods GetMinimumAllowedWidth() and GetMaximumAllowedWidth(), inherited from TextElement, return the constraints for either a specific TextNote or for a given document and text type id.
The following example creates a new TextNote at a user specified point and with a given width and TextNoteOptions.
**Code Region: Create a TextNote**
---
public TextNote AddNewTextNote(UIDocument uiDoc)
{
Document doc = uiDoc.Document;
XYZ textLoc = uiDoc.Selection.PickPoint("Pick a point for sample text.");
ElementId defaultTextTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType);
double noteWidth = .2;
// make sure note width works for the text type
double minWidth = TextNote.GetMinimumAllowedWidth(doc, defaultTextTypeId);
double maxWidth = TextNote.GetMaximumAllowedWidth(doc, defaultTextTypeId);
if (noteWidth < minWidth)
{
noteWidth = minWidth;
}
else if (noteWidth > maxWidth)
{
noteWidth = maxWidth;
}
TextNoteOptions opts = new TextNoteOptions(defaultTextTypeId);
opts.HorizontalAlignment = HorizontalTextAlignment.Left;
opts.Rotation = Math.PI / 4;
TextNote textNote = TextNote.Create(doc, doc.ActiveView.Id, textLoc, noteWidth, "New sample text", opts);
return textNote;
}
Whether a TextNote has plain or formatted text, the unformatted text can always be retrieved from the TextNote.Text property.
## FormattedText
When first created, the TextNote will have plain text. Use the TextNote.GetFormattedText() method to get a FormattedText object for the TextNote. The FormattedText class can be used to apply various formatting to the text such as bold, underline, superscript or all caps. The TextNote is not updated until SetFormattedText() is called with the modified FormattedText.
The text in the FormattedText can be formatted in whole or in part using a TextRange. A TextRange specifies a start index and length based on the text in the FormattedText object. When the overload of a formatting method (such as SetItalicStatus() or SetAllCapsStatus()) uses a TextRange, only the characters within the range will be modified. A TextRange can be defined explicitly using its constructor, or can be retrieved using the FormattedText.Find() method to get the range for a given search string. The Find() method specifies a start index for the search, as well as whether to match the case of the search string or whether to do a whole word search. If the text in the search string is not found or if the given start index is beyond the end of the length of the entire text, an empty TextRange will be returned. Before using the returned range to set formatting on the text, ensure that it is not empty to avoid an exception.
The following example demonstrates how to format text from a TextNote and set it back to the TextNote. It uses the Find() method to bold and underline specific words in the text.
**Code Region: Format text in a TextNote**
---
public void FormatText(TextNote textNote)
{
// TextNote created with "New sample text"
FormattedText formatText = textNote.GetFormattedText();
// italicize "New"
TextRange range = new TextRange(0, 3);
formatText.SetItalicStatus(range, true);
// make "sample" bold
range = formatText.Find("sample", 0, false, true);
if (range.Length > 0)
formatText.SetBoldStatus(range, true);
// make "text" underlined
range = formatText.Find("text", 0, false, true);
if (range.Length > 0)
formatText.SetUnderlineStatus(range, true);
// make all text uppercase
formatText.SetAllCapsStatus(true);
textNote.SetFormattedText(formatText);
}
New text can be added to existing text in a FormattedText object. The SetPlainText() method will either replace some existing text if the overload that has a TextRange parameter is used, or will replace the entire text if not. To insert text without replacing existing text, use a TextRange with a Length of 0. The new text will be inserted at the index specified by the TextRange.Start property. Note that when inserting text, it may pick up the formatting of the adjacent text, similar to how pasting unformatted text into a Word document will result in text with the current formatting for the insertion point. If formatting has been applied to the entire FormattedText as in the case of the SetAllCapsStatus(true) call in the example above, that formatting will be applied to any new text that is inserted.
In the following example, new text is appended to the end of existing text by first finding the end of the current text and setting that as the Start of the range to be added. It also demonstrates how to create a list (which can be bulleted, numbered or lettered). Note that it also calls GetAllCapsStatus() for the range of the new text and turns off caps if the status is not FormatStatus.None (other options are All and Mixed).
**Code Region: Inserting new text**
---
public void AppendText(TextNote textNote)
{
FormattedText formatText = textNote.GetFormattedText();
TextRange range = formatText.AsTextRange();
range.Start = range.End - 1;
// set Length to 0 to insert
range.Length = 0;
string someNewText = "\rThis is a new paragraph\vThis is a new line without a paragraph break\r";
formatText.SetPlainText(range, someNewText);
// get range for entire text
range = formatText.AsTextRange();
range.Start = range.End - 1;
range.Length = 0;
string someListText = "\rBulleted List item 1\rItem 2\vSecond line for Item 2\rThird bullet point";
formatText.SetPlainText(range, someListText);
range.Start++;
range.Length = someListText.Length;
formatText.SetListType(range, ListType.Bullet);
if (formatText.GetAllCapsStatus(range) != FormatStatus.None)
{
formatText.SetAllCapsStatus(range, false);
}
textNote.SetFormattedText(formatText);
}
The code above shows how to use \r to create a line break, and \v for a vertical tab that does not break the paragraph. In the text for the bulleted list, a "\v" is used to create a two line bullet point. A new bullet is only inserted when using "\r".
## Text Editor
The TextEditorOptions class can be used to control the appearance and functionality of the text editor in Revit. These settings are saved in the Revit.ini file and are not tied to the document.
The Revit.ini file is in the folder returned by the property Autodesk.Revit.ApplicationServices.Application.CurrentUsersDataFolderPath (such as %appdata%\Autodesk\Revit\Autodesk Revit 2025)
**Code Region: Setting text editor options**
---
public void SetEditorOptions()
{
TextEditorOptions editorOptions = TextEditorOptions.GetTextEditorOptions();
editorOptions.ShowBorder = false;
editorOptions.ShowOpaqueBackground = true;
}
## Leaders
Revit supports two kinds of Leaders: straight leaders and arc leaders. Leaders can be added to a TextNote using the AddLeader() method, specifying the leader type using the TextNoteLeaderType enumerated type:
**Table 39: Leader Types**
**Function** | **Member Name**
---|---
-Add a right arc leader | TNLT_ARC_R
-Add a left arc leader | TNLT_ARC_L
-Add a right leader. | TNLT_STRAIGHT_R
-Add a left leader. | TNLT_STRAIGHT_L
Note: Straight leaders and arc leaders cannot be added to a Text type at the same time.
The TextNote.LeaderCount property returns the number of leaders and the GetLeaders() method returns all leaders currently attached to the text component. LeaderLeftAttachment and LeaderRightAttachment indicate the attachment position of the leaders on the corresponding side of the TextNote. Options for the LeaderAttachment are TopLine, MidPoint, and BottomLine. Use the RemoveLeaders() method to remove all leaders from the TextNote.
**Parent page:** [Annotation Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html)

View File

@@ -0,0 +1,29 @@
# Annotation Elements
# Annotation Elements
This section covers Revit Annotation Elements, such as dimensions, text notes, keynotes, tags, and symbols.
Note that:
* Dimensions are view-specific elements that display sizes and distances in a project.
* Detail curves are created for detailed drawings. They are visible only in the view in which they are drawn. Often they are drawn over the model view.
* Tags are an annotation used to identify elements in a drawing. Properties associated with a tag can appear in schedules.
* AnnotationSymbol has multiple leader options when loaded into a project.
For more information about Revit Element classification, refer to [Elements Essentials](../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Elements_Essentials_html.html).
**Pages in this section**
* [Dimensions and Constraints](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Dimensions_and_Constraints_html.html)
* [Detail Curve](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Detail_Curve_html.html)
* [Tags](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Tags_html.html)
* [Text](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Text_html.html)
* [Annotation Symbol](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Annotation_Symbol_html.html)
* [Color Fill](Annotation_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_Color_Fill_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,34 @@
# Adaptive Components
# Adaptive Components
Adaptive Components are designed to handle cases where components need to flexibly adapt to many unique contextual conditions. For example, adaptive components could be used in repeating systems generated by arraying multiple components that conform to user-defined constraints.
The following code shows how to create an instance of an adaptive component family into a massing family and set the position of each point mathematically.
**Code Region: Creating an Instance of an Adaptive Component Family**
---
private void CreateAdaptiveComponentInstance(Document document, FamilySymbol symbol)
{
// Create a new instance of an adaptive component family
FamilyInstance instance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(document, symbol);
// Get the placement points of this instance
IList<ElementId> placePointIds = new List<ElementId>();
placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(instance);
double x = 0;
// Set the position of each placement point
foreach (ElementId id in placePointIds)
{
ReferencePoint point = document.GetElement(id) as ReferencePoint;
point.Position = new Autodesk.Revit.DB.XYZ(10*x, 10*Math.Cos(x), 0);
x += Math.PI/6;
}
}
To batch create adaptive components, you can use the overload of the FamilyInstanceCreationData constructor that takes two parameters - a FamilySymbol and a list of XYZ adaptive points where the adaptive instance is to be initialized. In conjunction with the Autodesk.Revit.Creation.ItemFactoryBase.NewFamilyInstances2() method which takes a list of FamilyInstanceCreationData objects, multiple adaptive components can be added at once. This may be more efficient than placing individual adaptive components one-by-one.
**Parent page:** [Conceptual Design](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_html.html)

View File

@@ -0,0 +1,41 @@
# Create a .addin manifest file
# Create a .addin manifest file
The HelloWorld.dll file appears in the project output directory. If you want to invoke the application in Revit, create a manifest file to register it into Revit.
To create a manifest file:
1. Create a new text file in Notepad.
2. Add the following text:
#### Code Region 30-10: Creating a .addin manifest file for an external command
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<RevitAddIns>
<AddIn Type="Command">
<Name>HelloWorld</Name>
<FullClassName>HelloWorld.HelloWorld</FullClassName>
<Text>HelloWorld</Text>
<Description>Show Hello World.</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Assembly>C:\Samples\HelloWorld\HelloWorld\bin\Debug\HelloWorld.dll</Assembly>
<AddInId>239BD853-36E4-461f-9171-C5ACEDA4E723</AddInId>
<VendorId>ADSK</VendorId>
<VendorDescription>Autodesk, Inc, www.autodesk.com</VendorDescription>
</AddIn>
</RevitAddIns>
Note: The FullClassName includes the Root namespace found on the Application tab of the properties for the project.
3. Save the file as HelloWorld.addin and put it in the following location:
* C:\ProgramData\Autodesk\Revit\Addins{{RelYear}}\
Refer to [Add-In Integration](../../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Add_In_Integration_html.html) for more details using manifest files.
**Parent page:** [Conceptual Design](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_html.html)

View File

@@ -0,0 +1,213 @@
# Forms
# Forms
### Creating Forms
Similar to family creation, the conceptual design environment provides the ability to create new forms. The following types of forms can be created: extrusions, revolves, sweeps, swept blends, lofts, and surface forms. Rather than using the Blend, Extrusion, Revolution, Sweep, and SweptBlend classes used in Family creation, Mass families use the Form class for all types of forms.
An extrusion form is created from a closed curve loop that is planar. A revolve form is created from a profile and a line in the same plane as the profile which is the axis around which the shape is revolved to create a 3D form. A sweep form is created from a 2D profile that is swept along a planar path. A swept blend is created from multiple profiles, each one planar, that is swept along a single curve. A loft form is created from 2 or more profiles located on separate planes. A single surface form is created from a profile, similarly to an extrusion, but is given no height.
The following example creates a simple extruded form. Note that since the ModelCurves used to create the form are not converted to reference lines, they will be consumed by the resulting form.
**Code Region 14-3: Creating an extrusion form**
---
private Form CreateExtrusionForm(Autodesk.Revit.DB.Document document)
{
Form extrusionForm = null;
// Create one profile
ReferenceArray ref_ar = new ReferenceArray();
XYZ ptA = new XYZ(10, 10, 0);
XYZ ptB = new XYZ(90, 10, 0);
ModelCurve modelcurve = MakeLine(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
ptA = new XYZ(90, 10, 0);
ptB = new XYZ(10, 90, 0);
modelcurve = MakeLine(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
ptA = new XYZ(10, 90, 0);
ptB = new XYZ(10, 10, 0);
modelcurve = MakeLine(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
// The extrusion form direction
XYZ direction = new XYZ(0, 0, 50);
extrusionForm = document.FamilyCreate.NewExtrusionForm(true, ref_ar, direction);
int profileCount = extrusionForm.ProfileCount;
return extrusionForm;
}
public ModelCurve MakeLine(Document doc, XYZ ptA, XYZ ptB)
{
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
// Create plane by the points
Line line = Line.CreateBound(ptA, ptB);
XYZ norm = ptA.CrossProduct(ptB);
if (norm.IsZeroLength()) norm = XYZ.BasisZ;
Plane plane = Plane.CreateByNormalAndOrigin(norm, ptB);
SketchPlane skplane = SketchPlane.Create(doc, plane);
// Create line here
ModelCurve modelcurve = doc.FamilyCreate.NewModelCurve(line, skplane);
return modelcurve;
}
**Figure 56: Resulting extrusion form**
The following example shows how to create loft form using a series of CurveByPoints objects.
**Code Region 14-4: Creating a loft form**
---
private Form CreateLoftForm(Document document)
{
Form loftForm = null;
ReferencePointArray rpa = new ReferencePointArray();
ReferenceArrayArray ref_ar_ar = new ReferenceArrayArray();
ReferenceArray ref_ar = new ReferenceArray();
ReferencePoint rp = null;
XYZ xyz = null;
// make first profile curve for loft
xyz = document.Application.Create.NewXYZ(0, 0, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 50, 10);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 100, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
CurveByPoints cbp = document.FamilyCreate.NewCurveByPoints(rpa);
ref_ar.Append(cbp.GeometryCurve.Reference);
ref_ar_ar.Append(ref_ar);
rpa.Clear();
ref_ar = new ReferenceArray();
// make second profile curve for loft
xyz = document.Application.Create.NewXYZ(50, 0, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(50, 50, 30);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(50, 100, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
cbp = document.FamilyCreate.NewCurveByPoints(rpa);
ref_ar.Append(cbp.GeometryCurve.Reference);
ref_ar_ar.Append(ref_ar);
rpa.Clear();
ref_ar = new ReferenceArray();
// make third profile curve for loft
xyz = document.Application.Create.NewXYZ(75, 0, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(75, 50, 5);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(75, 100, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
cbp = document.FamilyCreate.NewCurveByPoints(rpa);
ref_ar.Append(cbp.GeometryCurve.Reference);
ref_ar_ar.Append(ref_ar);
loftForm = document.FamilyCreate.NewLoftForm(true, ref_ar_ar);
return loftForm;
}
**Figure 57: Resulting loft form**
### Form modification
Once created, forms can be modified by changing a sub element (i.e. a face, edge, curve or vertex) of the form, or an entire profile. The methods to modify a form include:
* AddEdge
* AddProfile
* DeleteProfile
* DeleteSubElement
* MoveProfile
* MoveSubElement
* RotateProfile
* RotateSubElement
* ScaleSubElement
Additionally, you can modify a form by adding an edge or a profile, which can then be modified using the methods listed above.
The following example moves the first profile curve of the given form by a specified offset. The corresponding figure shows the result of applying this code to the loft form from the previous example.
**Code Region 14-5: Moving a profile**
---
public void MoveForm(Form form)
{
int profileCount = form.ProfileCount;
if (form.ProfileCount > 0)
{
int profileIndex = 0; // modify the first form only
if (form.CanManipulateProfile(profileIndex))
{
XYZ offset = new XYZ(-25, 0, 0);
form.MoveProfile(profileIndex, offset);
}
}
}
**Figure 58: Modified loft form**
The next sample demonstrates how to move a single vertex of a given form. The corresponding figure demonstrate the effect of this code on the previous extrusion form example.
**Code Region 14-6: Moving a sub element**
---
public void MoveSubElement(Form form)
{
Document document = form.Document;
if (form.ProfileCount > 0)
{
int profileIndex = 0; // get first profile
ReferenceArray ra = form.get_CurveLoopReferencesOnProfile(profileIndex, 0);
foreach (Reference r in ra)
{
ReferenceArray ra2 = form.GetControlPoints(r);
foreach (Reference r2 in ra2)
{
Point vertex = document.GetElement(r2).GetGeometryObjectFromReference(r2) as Point;
XYZ offset = new XYZ(0, 15, 0);
form.MoveSubElement(r2, offset);
break; // just move the first point
}
}
}
}
**Figure 59: Modified extrusion form**
**Parent page:** [Conceptual Design](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_html.html)

View File

@@ -0,0 +1,114 @@
# Point and curve objects
# Point and curve objects
A reference point is an element that specifies a location in the XYZ work space of the conceptual design environment. You create reference points to design and plot lines, splines, and forms. A ReferencePoint can be added to a ReferencePointArray, then used to create a CurveByPoints, which in turn can be used to create a form.
The following example demonstrates how to create a CurveByPoints object. See the "Creating a loft form" example in the next section to see how to create a form from multiple CurveByPoints objects.
**Code Region 14-1: Creating a new CurveByPoints**
---
public void CreateCurve(Document document)
{
ReferencePointArray rpa = new ReferencePointArray();
XYZ xyz = document.Application.Create.NewXYZ(0, 0, 0);
ReferencePoint rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 30, 10);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 60, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 100, 30);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
xyz = document.Application.Create.NewXYZ(0, 150, 0);
rp = document.FamilyCreate.NewReferencePoint(xyz);
rpa.Append(rp);
CurveByPoints curve = document.FamilyCreate.NewCurveByPoints(rpa);
}
**Figure 54: CurveByPoints curve**
Reference points can be created based on XYZ coordinates as in the example above, or they can be created relative to other geometry so that the points will move when the referenced geometry changes. These points are created using the subclasses of the PointElementReference class. The subclasses are:
* PointOnEdge
* PointOnEdgeEdgeIntersection
* PointOnEdgeFaceIntersection
* PointOnFace
* PointOnPlane
For example, the last two lines of code in the previous example create a reference point in the middle of the CurveByPoints.
Forms can be created using model lines or reference lines. Model lines are "consumed" by the form during creation and no longer exist as separate entities. Reference lines, on the other hand, persist after the form is created and can alter the form if they are moved. Although the API does not have a ReferenceLine class, you can change a model line to a reference line using the ModelCurve.ChangeToReferenceLine() method.
**Code Region 14-2: Using Reference Lines to create Form**
---
private FormArray CreateRevolveForm(Document document)
{
FormArray revolveForms = null;
// Create one profile
ReferenceArray ref_ar = new ReferenceArray();
XYZ ptA = new XYZ(0, 0, 10);
XYZ ptB = new XYZ(100, 0, 10);
Line line = Line.CreateBound(ptA, ptB);
ModelCurve modelcurve = MakeModelCurveFromTwoPoints(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
ptA = new XYZ(100, 0, 10);
ptB = new XYZ(100, 100, 10);
modelcurve = MakeModelCurveFromTwoPoints(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
ptA = new XYZ(100, 100, 10);
ptB = new XYZ(0, 0, 10);
modelcurve = MakeModelCurveFromTwoPoints(document, ptA, ptB);
ref_ar.Append(modelcurve.GeometryCurve.Reference);
// Create axis for revolve form
ptA = new XYZ(-5, 0, 10);
ptB = new XYZ(-5, 10, 10);
ModelCurve axis = MakeModelCurveFromTwoPoints(document, ptA, ptB);
// make axis a Reference Line
axis.ChangeToReferenceLine();
// Typically this operation produces only a single form,
// but some combinations of arguments will create multiple froms from a single profile.
revolveForms = document.FamilyCreate.NewRevolveForms(true, ref_ar, axis.GeometryCurve.Reference, 0, Math.PI / 4);
return revolveForms;
}
public ModelCurve MakeModelCurveFromTwoPoints(Document doc, XYZ ptA, XYZ ptB)
{
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
// Create plane by the points
Line line = Line.CreateBound(ptA, ptB);
XYZ norm = ptA.CrossProduct(ptB);
if (norm.IsZeroLength()) norm = XYZ.BasisZ;
Plane plane = Plane.CreateByNormalAndOrigin(norm, ptB);
SketchPlane skplane = SketchPlane.Create(doc, plane);
// Create line here
ModelCurve modelcurve = doc.FamilyCreate.NewModelCurve(line, skplane);
return modelcurve;
}
**Figure 55: Resulting Revolve Form**
**Parent page:** [Conceptual Design](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_html.html)

View File

@@ -0,0 +1,152 @@
# Rationalizing a Surface
# Rationalizing a Surface
### Dividing a surface
Faces of forms can be divided with UV grids. You can access the data for a divided surface using the DividedSurface.GetReferencesWithDividedSurface() and DividedSurface.GetDividedSurfaceForReference() methods (as is shown in a subsequent example) as well as create new divided surfaces on forms as shown below.
**Code Region 14-7: Dividing a surface**
---
public void DivideSurface(Document document, Form form)
{
Autodesk.Revit.ApplicationServices.Application application = document.Application;
Options opt = application.Create.NewGeometryOptions();
opt.ComputeReferences = true;
Autodesk.Revit.DB.GeometryElement geomElem = form.get_Geometry(opt);
foreach (GeometryObject geomObj in geomElem)
{
Solid solid = geomObj as Solid;
foreach (Face face in solid.Faces)
{
if (face.Reference != null)
{
DividedSurface ds = DividedSurface.Create(document,face.Reference);
// create a divided surface with fixed number of U and V grid lines
SpacingRule srU = ds.USpacingRule;
srU.SetLayoutFixedNumber(16, SpacingRuleJustification.Center, 0, 0);
SpacingRule srV = ds.VSpacingRule;
srV.SetLayoutFixedNumber(24, SpacingRuleJustification.Center, 0, 0);
break; // just divide one face of form
}
}
}
}
**Figure 60: Face of form divided by UV grids**
Accessing the USpacing and VSpacing properties of DividedSurface, you can define the SpacingRule for the U and V gridlines by specifying either a fixed number of grids (as in the example above), a fixed distance between grids, or a minimum or maximum spacing between grids. Additional information is required for each spacing rule, such as justification and grid rotation.
### Patterning a surface
A divided surface can be patterned. Any of the built-in tile patterns can be applied to a divided surface. A tile pattern is an ElementType that is assigned to the DividedSurface. The tile pattern is applied to the surface according to the UV grid layout, so changing the USpacing and VSpacing properties of the DividedSurface will affect how the patterned surface appears.
The following example demonstrates how to cover a divided surface with the OctagonRotate pattern. The corresponding figure shows how this looks when applied to the divided surface in the previous example. Note this example also demonstrates how to get a DividedSurface on a form.
**Code Region 14-8: Patterning a surface**
---
public void TileSurface(Document document, Form form)
{
// cover surface with OctagonRotate tile pattern
TilePatterns tilePatterns = document.Settings.TilePatterns;
foreach (Reference r in DividedSurface.GetReferencesWithDividedSurfaces(form))
{
DividedSurface ds = DividedSurface.GetDividedSurfaceForReference(document, r);
ds.ChangeTypeId(tilePatterns.GetTilePattern(TilePatternsBuiltIn.OctagonRotate).Id);
}
}
**Figure 61: Tile pattern applied to divided surface**
In addition to applying built-in tile patterns to a divided surface, you can create your own massing panel families using the "Curtain Panel Pattern Based.rft" template. These panel families can then be loaded into massing families and applied to divided surfaces using the DividedSurface.ChangeTypeId() method.
The following properties of Family are specific to curtain panel families:
* IsCurtainPanelFamily
* CurtainPanelHorizontalSpacing - horizontal spacing of driving mesh
* CurtainPanelVerticalSpacing - vertical spacing of driving mesh
* CurtainPanelTilePattern - choice of tile pattern
The following example demonstrates how to edit a massing panel family which can then be applied to a form in a conceptual mass document. To run this example, first create a new family document using the "Curtain Panel Pattern Based.rft" template.
**Code Region 14-9: Editing a curtain panel family**
---
public void EditCurtainPanel(Document document)
{
Family family = document.OwnerFamily;
if (family.IsCurtainPanelFamily == true &&
family.CurtainPanelTilePattern == TilePatternsBuiltIn.Rectangle)
{
// first change spacing of grids in family document
family.CurtainPanelHorizontalSpacing = 20;
family.CurtainPanelVerticalSpacing = 30;
// create new points and lines on grid
Autodesk.Revit.ApplicationServices.Application app = document.Application;
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> collection = collector.OfClass(typeof(ReferencePoint)).ToElements();
int ctr = 0;
ReferencePoint rp0 = null, rp1 = null, rp2 = null, rp3 = null;
foreach (Autodesk.Revit.DB.Element e in collection)
{
ReferencePoint rp = e as ReferencePoint;
switch (ctr)
{
case 0:
rp0 = rp;
break;
case 1:
rp1 = rp;
break;
case 2:
rp2 = rp;
break;
case 3:
rp3 = rp;
break;
}
ctr++;
}
ReferencePointArray rpAr = new ReferencePointArray();
rpAr.Append(rp0);
rpAr.Append(rp2);
CurveByPoints curve1 = document.FamilyCreate.NewCurveByPoints(rpAr);
PointLocationOnCurve pointLocationOnCurve25 = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, 0.25, PointOnCurveMeasureFrom.Beginning);
PointOnEdge poeA = app.Create.NewPointOnEdge(curve1.GeometryCurve.Reference, pointLocationOnCurve25);
ReferencePoint rpA = document.FamilyCreate.NewReferencePoint(poeA);
PointLocationOnCurve pointLocationOnCurve75 = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, 0.75, PointOnCurveMeasureFrom.Beginning);
PointOnEdge poeB = app.Create.NewPointOnEdge(curve1.GeometryCurve.Reference, pointLocationOnCurve75);
ReferencePoint rpB = document.FamilyCreate.NewReferencePoint(poeB);
rpAr.Clear();
rpAr.Append(rp1);
rpAr.Append(rp3);
CurveByPoints curve2 = document.FamilyCreate.NewCurveByPoints(rpAr);
PointOnEdge poeC = app.Create.NewPointOnEdge(curve2.GeometryCurve.Reference, pointLocationOnCurve25);
ReferencePoint rpC = document.FamilyCreate.NewReferencePoint(poeC);
PointOnEdge poeD = app.Create.NewPointOnEdge(curve2.GeometryCurve.Reference, pointLocationOnCurve75);
ReferencePoint rpD = document.FamilyCreate.NewReferencePoint(poeD);
}
else
{
throw new Exception("Please open a curtain family document before calling this command.");
}
}
**Figure 62: Curtain panel family**
**Figure 63: Curtain panel assigned to divided surface**
**Parent page:** [Conceptual Design](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_html.html)

View File

@@ -0,0 +1,17 @@
# Conceptual Design
# Conceptual Design
This chapter discusses the conceptual design functionality of the Revit API for the creation of complex geometry in a family document. Form-making is supported by the addition of new objects: points and spline curves that pass through these points. The resulting surfaces can be divided, patterned, and panelized to create buildable forms with persistent parametric relationships.
**Pages in this section**
* [Point and curve objects](Conceptual_Design/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_Point_and_curve_objects_html.html)
* [Forms](Conceptual_Design/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_Forms_html.html)
* [Rationalizing a Surface](Conceptual_Design/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_Rationalizing_a_Surface_html.html)
* [Adaptive Components](Conceptual_Design/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_Adaptive_Components_html.html)
* [Create a .addin manifest file](Conceptual_Design/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Conceptual_Design_Create_a_addin_manifest_file_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,40 @@
# Design Options
# Design Options
Design options provide a way to explore alternative designs in a project.
Design options provide the flexibility to adapt to changes in project scope or to develop alternative designs for review. You can begin work with the main project model and then develop variations along the way to present to a client. Most elements can be added into a design option. Elements that cannot be added into a design option are considered part of the main model and have no design alternatives.
The main use for Design options is as a property of the Element class. See the following example.
**Code Region 15-7: Using design options**
---
void Getinfo_DesignOption(Document document)
{
// Get the selected Elements in the Active Document
UIDocument uidoc = new UIDocument(document);
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
foreach (ElementId id in selectedIds)
{
Element element = document.GetElement(id);
//Use the DesignOption property of Element
if (element.DesignOption != null)
{
TaskDialog.Show("Revit",element.DesignOption.Name.ToString());
}
}
}
The following rules apply to Design Options
* The value of the DesignOption property is null if the element is in the Main Model. Otherwise, the name you created in the Revit UI is returned.
* Only one active DesignOption Element can exist in an ActiveDocument.
* The primary option is considered the default active DesignOption. For example, a design option set is named Wall and there are two design options in this set named "brick wall" and "glass wall". If "brick wall" is the primary option, only this option and elements that belong to it are retrieved by the Element Iterator. "Glass wall" is inactive.
**Parent page:** [Datum and Information Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_html.html)

View File

@@ -0,0 +1,119 @@
# Grids
# Grids
The Grid class represents a single grid line within Autodesk Revit.
Grids are represented by the Grid class which is derived from the DatumPlane class, which is derived from the Element class. It contains all grid properties and methods. The inherited Name property is used to retrieve the content of the grid line's bubble.
### Curve
The Grid class Curve property gets the object that represents the grid line geometry.
* If the IsCurved property returns true, the Curve property will be an Arc class object.
* If the IsCurved property returns false, the Curve property will be a Line class object.
For more information, refer to [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html).
The following code is a simple example using the Grid class. The result appears in a message box after invoking the command.
**Code Region 15-3: Using the Grid class**
---
public void GetInfo_Grid(Grid grid)
{
string message = "Grid : ";
// Show IsCurved property
message += "\nIf grid is Arc : " + grid.IsCurved;
// Show Curve information
Autodesk.Revit.DB.Curve curve = grid.Curve;
if (grid.IsCurved)
{
// if the curve is an arc, give center and radius information
Autodesk.Revit.DB.Arc arc = curve as Autodesk.Revit.DB.Arc;
message += "\nArc's radius: " + arc.Radius;
message += "\nArc's center: (" + XYZString(arc.Center);
}
else
{
// if the curve is a line, give length information
Autodesk.Revit.DB.Line line = curve as Autodesk.Revit.DB.Line;
message += "\nLine's Length: " + line.Length;
}
// Get curve start point
message += "\nStart point: " + XYZString(curve.GetEndPoint(0));
// Get curve end point
message += "; End point: " + XYZString(curve.GetEndPoint(0));
TaskDialog.Show("Revit",message);
}
// output the point's three coordinates
private string XYZString(XYZ point)
{
return "(" + point.X + ", " + point.Y + ", " + point.Z + ")";
}
### Creating a Grid
Two overloaded Create() methods are available in the Grid class to create a new grid in the Revit Platform API. Using the following method with different parameters, you can create a curved or straight grid:
**Code Region 15-4: Grid.Create()**
---
public Grid Create( Document document, Arc arc );
public Grid Create( Document document, Line line );
Note: The arc or the line used to create a grid must be in a horizontal plane.
The following code sample illustrates how to create a new grid with a line or an arc.
**Code Region 15-5: Creating a grid with a line or an arc**
---
void CreateGrid(Autodesk.Revit.DB.Document document)
{
// Create the geometry line which the grid locates
XYZ start = new XYZ(0, 0, 0);
XYZ end = new XYZ(30, 30, 0);
Line geomLine = Line.CreateBound(start, end);
// Create a grid using the geometry line
Grid lineGrid = Grid.Create(document, geomLine);
if (null == lineGrid)
{
throw new Exception("Create a new straight grid failed.");
}
// Modify the name of the created grid
lineGrid.Name = "New Name1";
// Create the geometry arc which the grid locates
XYZ end0 = new XYZ(0, 0, 0);
XYZ end1 = new XYZ(10, 40, 0);
XYZ pointOnCurve = new XYZ(5, 7, 0);
Arc geomArc = Arc.Create(end0, end1, pointOnCurve);
// Create a grid using the geometry arc
Grid arcGrid = Grid.Create(document, geomArc);
if (null == arcGrid)
{
throw new Exception("Create a new curved grid failed.");
}
// Modify the name of the created grid
arcGrid.Name = "New Name2";
}
Note: In Revit, the grids are named automatically in a numerical or alphabetical sequence when they are created.
**Parent page:** [Datum and Information Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_html.html)

View File

@@ -0,0 +1,100 @@
# Levels
# Levels
A level is a finite horizontal plane that acts as a reference for level-hosted elements, such as walls, roofs, floors, and ceilings.
In the Revit Platform API, the Level class is derived from the DatumPlane class, which is derived from the Element class. The inherited Name property is used to retrieve the user-visible level name beside the level bubble in the Revit UI. To retrieve all levels in a project, use an ElementClassFilter with the Level class.
## Elevation
The Level class has the following properties:
* The Elevation property is used to retrieve or change the elevation above or below ground level.
* The ProjectElevation property is used to retrieve the elevation relative to the project origin regardless of the Elevation Base parameter value.
* The Elevation Base value is a Level type parameter.
* Its BuiltInParameter is LEVEL_RELATIVE_BASE_TYPE.
* Its StorageType is Integer.
* 0 corresponds to Project and 1 corresponds to Shared.
The following code sample illustrates how to retrieve all levels in a project using a Level class filter.
**Code Region 15-1: Retrieving all Levels**
---
private void Getinfo_Level(Document document)
{
StringBuilder levelInformation = new StringBuilder();
int levelNumber = 0;
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> collection = collector.OfClass(typeof(Level)).ToElements();
foreach (Element e in collection)
{
Level level = e as Level;
if (null != level)
{
// keep track of number of levels
levelNumber++;
//get the name of the level
levelInformation.Append("\nLevel Name: " + level.Name);
//get the elevation of the level
levelInformation.Append("\n\tElevation: " + level.Elevation);
// get the project elevation of the level
levelInformation.Append("\n\tProject Elevation: " + level.ProjectElevation);
}
}
//number of total levels in current document
levelInformation.Append("\n\n There are " + levelNumber + " levels in the document!");
//show the level information in the messagebox
TaskDialog.Show("Revit",levelInformation.ToString());
}
## Creating a Level
Using the Level command, you can define a vertical height or story within a building and you can create a level for each existing story or other building references. Levels must be added in a section or elevation view. Additionally, you can create a new level using the Revit Platform API.
The following code sample illustrates how to create a new level.
**Code Region 15-2: Creating a new Level**
---
Level CreateLevel(Autodesk.Revit.DB.Document document)
{
// The elevation to apply to the new level
double elevation = 20.0;
// Begin to create a level
Level level = Level.Create(document, elevation);
if (null == level)
{
throw new Exception("Create a new level failed.");
}
// Change the level name
level.Name = "New level";
return level;
}
Note: After creating a new level, Revit does not create the associated plan view for this level. If necessary, you can create it yourself.
## Finding levels based on elevation
You can find levels based on their elevation with a `FilteredElementCollector`. You can also use one of these static methods which return the id of the Level which is closest to the specified elevation. The level can be at, above, or below the target elevation. If there is more than one Level at the same distance from the elevation, the Level with the lowest id will be returned.
* Level.GetNearestLevelId(Document document, double elevation)
* Level.GetNearestLevelId(Document document, double elevation, out double offset)
**Parent page:** [Datum and Information Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_html.html)

View File

@@ -0,0 +1,69 @@
# Phase
# Phase
Some architectural projects, such as renovations, proceed in phases. Phases have the following characteristics:
* Phases represent distinct time periods in a project lifecycle.
* The lifetime of an element within a building is controlled by phases.
* Each element has a construction phase but only the elements with a finite lifetime have a destruction phase.
All phases in a project can be retrieved from the Document object. A Phase object contains three pieces of useful information: Name, ID and UniqueId. The remaining properties always return null or an empty collection.
Each new modeling component added to a project has a Created Phase ID and a Demolished Phase ID property. The Element.AllowPhases() method indicates whether its phase ID properties can be modified.
The Created Phase ID property has the following characteristics:
* It identifies the phase in which the component was added.
* The default value is the same ID as the current view Phase value.
* Change the Created Phase ID parameter by selecting a new value corresponding to the drop-down list.
The Demolished Phase ID property has the following characteristics:
* It identifies in which phase the component is demolished.
* The default value is none.
* Demolishing a component with the demolition tool updates the property to the current Phase ID value in the view where you demolished the element.
* You can demolish a component by setting the Demolished Phase ID property to a different value.
* If you delete a phase using the Revit Platform API, all modeling components in the current phase still exist. The Created Phase ID parameter value for these components is changed to the next item in the drop-down list in the Properties dialog box.
**Figure 65: Phase-created component parameter value**
The following code sample displays all supported phases in the current document. The phase names are displayed in a message box.
**Code Region 15-6: Displaying all supported phases**
---
void Getinfo_Phase(Document doc)
{
// Get the phase array which contains all the phases.
PhaseArray phases = doc.Phases;
// Format the string which identifies all supported phases in the current document.
String prompt = null;
if (0 != phases.Size)
{
prompt = "All the phases in current document list as follow:";
foreach (Phase ii in phases)
{
prompt += "\n\t" + ii.Name;
}
}
else
{
prompt = "There are no phases in current document.";
}
// Give the user the information.
TaskDialog.Show("Revit",prompt);
}
## Validating phase data of an element
`Element.IsDemolishedPhaseOrderValid()` and `Element.IsCreatedPhaseOrderValid()` validate the order of phases on a given element, ensuring that an object is not assigned a phase where it is demolished before it was created.
**Parent page:** [Datum and Information Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_html.html)

View File

@@ -0,0 +1,32 @@
# Datum and Information Elements
# Datum and Information Elements
This chapter introduces Datum Elements and Information Elements in Revit.
* Datum Elements include levels, grids, and ModelCurves.
* Information Elements include phases, design options, and EnergyDataSettings.
For more information about Revit Element classifications, refer to [Elements Essentials](../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Elements_Essentials_html.html).
If you need more information, refer to the related chapter:
* For LoadBase, LoadCase, LoadCombination, LoadNature and LoadUsage, refer to [Structural Engineering](../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html).
* For ModelCurve, refer to [Sketching](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_html.html).
* For Material and FillPattern, refer to [Material](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html).
* For EnergyDataSettings, refer to [Energy Data](../Advanced_Topics/Analysis/Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Analysis_Energy_Data_html.html).
**Pages in this section**
* [Levels](Datum_and_Information_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_Levels_html.html)
* [Grids](Datum_and_Information_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_Grids_html.html)
* [Phase](Datum_and_Information_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_Phase_html.html)
* [Design Options](Datum_and_Information_Elements/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Datum_and_Information_Elements_Design_Options_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,386 @@
# DirectShape
# DirectShape
This element type can store arbitrary geometry created by the Revit API or obtained from import operations or calculations in either a project or family document.
The DirectShape element and related classes support the ability to store externally created geometric shapes in a Revit document. The geometry can include closed solids or meshes. DirectShape is primarily intended for importing shapes from other data formats such as IFC or STEP where not enough information is available to create a "real" Revit element.
A DirectShape object may be assigned a top-level Model category, such as the Wall category. Sub-categories cannot be assigned to DirectShape elements. The IsValidCategoryId() method can test a category id to make sure it is a top-level built-in category approved for use with DirectShape and the Category.CategoryType enumerated value will indicated if the category type is Model. Assigning a category will affect how that object is displayed in Revit and will grant the object a collection of available parameters and some limited behaviors.
## Creation
The static CreateElement() method will create a new instance-level DirectShape. It requires the document in which the DirectShape will be added and the id of an appropriate built-in category. DirectShape provides the ApplicationId and ApplicationDataId string parameters that provide context for the source of the created shape.
Once the DirectShape is created, the shape can be set using one of the overloaded SetShape() method. The shape can be set either directly from a ShapeBuilder object or from a list of GeometryObjects. If you are using a ShapeBuilder object to construct geometry for the DirectShape anyway, there may be a slight performance advantage to using the ShapeBuilder input, as Revit will bypass repetitive validation of the input geometry. It is also possible to append additional geometry objects to the DirectShape using versions of the AppendShape() method. Note that AppendShape() will not merge or join the incoming geometry with any geometry already present, the geometry will be stored independently.
DirectShapes accept the following geometry types as input:
* Solid (this can be a closed or open shell)
* Mesh
* Curve
* Point
In addition, you can specify geometry to be used in a view-specific representation of a DirectShape. This geometry is input along with the input of a DirectShapeTargetViewType. When setting a view-specific shape representation, it will only be used in views of that type. Currently the only view-specific representation supported is for Plan views.
`DirectShapeType.SetFamilyName()` provides the ability to set a custom Family name for a DirectShapeType. The validator: `DirectShapeType.CanChangeFamilyName()` provides the ability to check if a DirectShapeType supports a custom Family name because certain categories do not support custom Family names.
The following example demonstrates how to create a simple DirectShape from a sphere created using the GeometryCreationUtilities class. Note the use of a reference Frame in creating the geometry. Prior to using it to create geometry, it is good practice to call the static method Frame.CanDefineRevitGeometry() which tests whether the supplied Frame object may be used to define a Revit curve or surface. In order to satisfy the requirements the Frame must be orthonormal and its origin is expected to lie within the Revit design limits. (When creating geometry, it also can be useful to use the static XYZ. IsWithinLengthLimits() to ensure the point is within Revit design limits.)
**Code Region: Create a DirectShape**
---
// Create a DirectShape Sphere
public void CreateSphereDirectShape(Document doc)
{
List<Curve> profile = new List<Curve>();
// first create sphere with 2' radius
XYZ center = XYZ.Zero;
double radius = 2.0;
XYZ profile00 = center;
XYZ profilePlus = center + new XYZ(0, radius, 0);
XYZ profileMinus = center - new XYZ(0, radius, 0);
profile.Add(Line.CreateBound(profilePlus, profileMinus));
profile.Add(Arc.Create(profileMinus, profilePlus, center + new XYZ(radius, 0, 0)));
CurveLoop curveLoop = CurveLoop.Create(profile);
SolidOptions options = new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId);
Frame frame = new Frame(center, XYZ.BasisX, -XYZ.BasisZ, XYZ.BasisY);
if (Frame.CanDefineRevitGeometry(frame) == true)
{
Solid sphere = GeometryCreationUtilities.CreateRevolvedGeometry(frame, new CurveLoop[] { curveLoop }, 0, 2 * Math.PI, options);
using (Transaction t = new Transaction(doc, "Create sphere direct shape"))
{
t.Start();
// create direct shape and assign the sphere shape
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.ApplicationId = "Application id";
ds.ApplicationDataId = "Geometry object id";
ds.SetShape(new GeometryObject[] { sphere });
t.Commit();
}
}
}
The geometry for a DirectShape can also be created using a subclass of the ShapeBuilder class or from a TessellatedShapeBuilder.
## ShapeBuilder
ViewShapeBuilder and WireframeBuilder can be used to create geometry to store in a DirectShape class. The ViewShapeBuilder class builds and verifies a view-specific shape representation. It is limited to curve-based representations for plan views. WireframeBuilder constructs a 3D shape representation consisting of points and curves. Both types of ShapeBuilders can be applied to a DirectShape element using the DirectShape.SetShape() or DirectShape.AppendShape() overload that takes a ShapeBuilder parameter.
## TessellatedShapeBuilder
TessellatedShapeBuilder can be used create solid, shell, or polymeshes bounded by a set of connected planar facets, created by adding TessellatedFace objects one by one. Faces can only be added to the build while a face set is "open". Use the OpenConnectedFaceSet() method to open a face set. After adding all the TessellatedFaces, call CloseConnectedFaceSet() to close the face set. The builder allows for the possibility of multiple face sets - in such cases the first set should represent the outer 'surface' of a body and all following sets represent interior voids. The builder tries to create a geometry valid in Revit despite inconsistencies or omissions in the input data.
After defining all faces and closing the face set, call the Build() method to build the designated geometrical objects from the stored face sets. The Target, Fallback and GraphicsStyleId properties of the TessellatedShapeBuilder can be set prior to calling Build() or default options will be used. The results of Build() are stored in the TessellatedShapeBuilder and can be retrieved by calling GetBuildResult(). The TessellatedShapeBuilderResult.GetGeometricalObjects() method will return a list of GeometryObjects which can be used with the corresponding DirectShape.SetShape() or DirectShape.AppendShape() overload, as shown in the example below.
**Code Region: Create a DirectShape using TessellatedShapeBuilder**
---
// Create a pyramid-shaped DirectShape using given material for the faces
public void CreateTessellatedShape(Document doc, ElementId materialId)
{
List<XYZ> loopVertices = new List<XYZ>(4);
TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
builder.OpenConnectedFaceSet(true);
// create a pyramid with a square base 4' x 4' and 5' high
double length = 4.0;
double height = 5.0;
XYZ basePt1 = XYZ.Zero;
XYZ basePt2 = new XYZ(length, 0, 0);
XYZ basePt3 = new XYZ(length, length, 0);
XYZ basePt4 = new XYZ(0, length, 0);
XYZ apex = new XYZ(length / 2, length / 2, height);
loopVertices.Add(basePt1);
loopVertices.Add(basePt2);
loopVertices.Add(basePt3);
loopVertices.Add(basePt4);
builder.AddFace(new TessellatedFace(loopVertices, materialId));
loopVertices.Clear();
loopVertices.Add(basePt1);
loopVertices.Add(apex);
loopVertices.Add(basePt2);
builder.AddFace(new TessellatedFace(loopVertices, materialId));
loopVertices.Clear();
loopVertices.Add(basePt2);
loopVertices.Add(apex);
loopVertices.Add(basePt3);
builder.AddFace(new TessellatedFace(loopVertices, materialId));
loopVertices.Clear();
loopVertices.Add(basePt3);
loopVertices.Add(apex);
loopVertices.Add(basePt4);
builder.AddFace(new TessellatedFace(loopVertices, materialId));
loopVertices.Clear();
loopVertices.Add(basePt4);
loopVertices.Add(apex);
loopVertices.Add(basePt1);
builder.AddFace(new TessellatedFace(loopVertices, materialId));
builder.CloseConnectedFaceSet();
builder.Target = TessellatedShapeBuilderTarget.Solid;
builder.Fallback = TessellatedShapeBuilderFallback.Abort;
builder.Build();
TessellatedShapeBuilderResult result = builder.GetBuildResult();
using (Transaction t = new Transaction(doc, "Create tessellated direct shape"))
{
t.Start();
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.ApplicationId = "Application id";
ds.ApplicationDataId = "Geometry object id";
ds.SetShape(result.GetGeometricalObjects());
t.Commit();
}
}
The image below is the result of running the example above with a concrete material id specified.
## BRepBuilder
The BRepBuilder class offers the ability to construct Revit boundary representation geometry (solids, open shells, etc.) as a result of inputs of surfaces, edges, and boundary loops of edges. If the construction of the boundary representation is successful, the resulting geometry objects can be used directly in any other Revit tool that accepts geometry, or the BRepBuilder can be passed directly to populate a DirectShape via the SetShape() and AppendShape() methods of the DirectShape class. Below is an example of using the SetShape() method to assign a cylinder shape to a new DirectShape object.
**Code Region: Create a DirectShape using BRepBuilder**
---
private void CreateDirectShapeFromCylinder(Document doc)
{
// Naming convention for faces and edges: we assume that x is to the left and pointing down, y is horizontal and pointing to the right, z is up
BRepBuilder brepBuilder = new BRepBuilder(BRepType.Solid);
// The surfaces of the four faces.
Frame basis = new Frame(new XYZ(50, -100, 0), new XYZ(0, 1, 0), new XYZ(-1, 0, 0), new XYZ(0, 0, 1));
CylindricalSurface cylSurf = CylindricalSurface.Create(basis, 50);
Plane top = Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 100)); // normal points outside the cylinder
Plane bottom = Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0)); // normal points inside the cylinder
// Add the four faces
BRepBuilderGeometryId frontCylFaceId = brepBuilder.AddFace(BRepBuilderSurfaceGeometry.Create(cylSurf, null), false);
BRepBuilderGeometryId backCylFaceId = brepBuilder.AddFace(BRepBuilderSurfaceGeometry.Create(cylSurf, null), false);
BRepBuilderGeometryId topFaceId = brepBuilder.AddFace(BRepBuilderSurfaceGeometry.Create(top, null), false);
BRepBuilderGeometryId bottomFaceId = brepBuilder.AddFace(BRepBuilderSurfaceGeometry.Create(bottom, null), true);
// Geometry for the four semi-circular edges and two vertical linear edges
BRepBuilderEdgeGeometry frontEdgeBottom = BRepBuilderEdgeGeometry.Create(Arc.Create(new XYZ(0, -100, 0), new XYZ(100, -100, 0), new XYZ(50, -50, 0)));
BRepBuilderEdgeGeometry backEdgeBottom = BRepBuilderEdgeGeometry.Create(Arc.Create(new XYZ(100, -100, 0), new XYZ(0, -100, 0), new XYZ(50, -150, 0)));
BRepBuilderEdgeGeometry frontEdgeTop = BRepBuilderEdgeGeometry.Create(Arc.Create(new XYZ(0, -100, 100), new XYZ(100, -100, 100), new XYZ(50, -50, 100)));
BRepBuilderEdgeGeometry backEdgeTop = BRepBuilderEdgeGeometry.Create(Arc.Create(new XYZ(0, -100, 100), new XYZ(100, -100, 100), new XYZ(50, -150, 100)));
BRepBuilderEdgeGeometry linearEdgeFront = BRepBuilderEdgeGeometry.Create(new XYZ(100, -100, 0), new XYZ(100, -100, 100));
BRepBuilderEdgeGeometry linearEdgeBack = BRepBuilderEdgeGeometry.Create(new XYZ(0, -100, 0), new XYZ(0, -100, 100));
// Add the six edges
BRepBuilderGeometryId frontEdgeBottomId = brepBuilder.AddEdge(frontEdgeBottom);
BRepBuilderGeometryId frontEdgeTopId = brepBuilder.AddEdge(frontEdgeTop);
BRepBuilderGeometryId linearEdgeFrontId = brepBuilder.AddEdge(linearEdgeFront);
BRepBuilderGeometryId linearEdgeBackId = brepBuilder.AddEdge(linearEdgeBack);
BRepBuilderGeometryId backEdgeBottomId = brepBuilder.AddEdge(backEdgeBottom);
BRepBuilderGeometryId backEdgeTopId = brepBuilder.AddEdge(backEdgeTop);
// Loops of the four faces
BRepBuilderGeometryId loopId_Top = brepBuilder.AddLoop(topFaceId);
BRepBuilderGeometryId loopId_Bottom = brepBuilder.AddLoop(bottomFaceId);
BRepBuilderGeometryId loopId_Front = brepBuilder.AddLoop(frontCylFaceId);
BRepBuilderGeometryId loopId_Back = brepBuilder.AddLoop(backCylFaceId);
// Add coedges for the loop of the front face
brepBuilder.AddCoEdge(loopId_Front, linearEdgeBackId, false);
brepBuilder.AddCoEdge(loopId_Front, frontEdgeTopId, false);
brepBuilder.AddCoEdge(loopId_Front, linearEdgeFrontId, true);
brepBuilder.AddCoEdge(loopId_Front, frontEdgeBottomId, true);
brepBuilder.FinishLoop(loopId_Front);
brepBuilder.FinishFace(frontCylFaceId);
// Add coedges for the loop of the back face
brepBuilder.AddCoEdge(loopId_Back, linearEdgeBackId, true);
brepBuilder.AddCoEdge(loopId_Back, backEdgeBottomId, true);
brepBuilder.AddCoEdge(loopId_Back, linearEdgeFrontId, false);
brepBuilder.AddCoEdge(loopId_Back, backEdgeTopId, true);
brepBuilder.FinishLoop(loopId_Back);
brepBuilder.FinishFace(backCylFaceId);
// Add coedges for the loop of the top face
brepBuilder.AddCoEdge(loopId_Top, backEdgeTopId, false);
brepBuilder.AddCoEdge(loopId_Top, frontEdgeTopId, true);
brepBuilder.FinishLoop(loopId_Top);
brepBuilder.FinishFace(topFaceId);
// Add coedges for the loop of the bottom face
brepBuilder.AddCoEdge(loopId_Bottom, frontEdgeBottomId, false);
brepBuilder.AddCoEdge(loopId_Bottom, backEdgeBottomId, false);
brepBuilder.FinishLoop(loopId_Bottom);
brepBuilder.FinishFace(bottomFaceId);
brepBuilder.Finish();
using (Transaction tr = new Transaction(doc, "Create a DirectShape"))
{
tr.Start();
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.SetShape(brepBuilder);
tr.Commit();
}
}
## ShapeImporter
The ShapeImporter utility class supports conversion of geometry stored in external formats (such as SAT and Rhino) into a collection of GeometryObjects which can be used to set the shape for a DirectShape. Use ShapeImporter.Convert() to generate the geometry objects (and where possible, corresponding materials and graphics styles in the associated document).
**Code Region: Create a DirectShape from SAT file**
---
public void ReadSATFile(Document revitDoc)
{
// Allow the user to select a SAT file.
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
ofd.Filter = "SAT Files (*.sat)|*.sat";
if (System.Windows.Forms.DialogResult.OK == ofd.ShowDialog())
{
ShapeImporter shapeImporter = new ShapeImporter();
shapeImporter.InputFormat = ShapeImporterSourceFormat.SAT;
IList<GeometryObject> shapes = shapeImporter.Convert(revitDoc, ofd.FileName);
if (shapes.Count != 0)
{
using (Transaction tr = new Transaction(revitDoc, "Create a DirectShape"))
{
tr.Start();
DirectShape dsImportedSat = DirectShape.CreateElement(revitDoc, new ElementId(BuiltInCategory.OST_Walls));
dsImportedSat.SetShape(shapes);
tr.Commit();
}
}
}
}
## Reference Curves, Planes, and Points
The methods:
* DirectShape.AddReferenceCurve()
* DirectShape.AddReferencePlane()
* DirectShape.AddReferencePoint()
* DirectShapeType.AddReferenceCurve()
* DirectShapeType.AddReferencePlane()
* DirectShapeType.AddReferencePoint()
enable the creation of reference curves, planes and points inside DirectShape elements. Explicit bounds can be provided for direct shape reference curves and planes. Revit tools that can use named references within families will also be able to select the references inside the DirectShape elements.
The overloads for these methods include an optional `DirectShapeReferenceOptions` input. Use `DirectShapeReferenceOptions.Name` to set the assigned name for the reference. If the name is specified, it is visible when picking the reference's geometry. Otherwise, the default DirectShape element name is displayed. The validator `DirectShapeReferenceOptions.IsValidReferenceName()` validates the name assigned to DirectShapeReferenceOptions.Name.
The validators:
* DirectShape.IsValidReferenceCurve()
* DirectShape.IsValidReferencePlaneBoundingBoxUV()
* DirectShapeType.IsValidReferenceCurve()
* DirectShapeType.IsValidReferencePlaneBoundingBoxUV()
validates the inputs needed for specifying a plane or curve explicit reference in the DirectShape.
## Options
The DirectShapeOptions class is used to control behavior of a DirectShape object. Use DirectShape.SetOptions() to set the options used by a DirectShape object. The GetOptions() method will return the DirectShapeOptions currently used by the DirectShape object.
DirectShape elements, by default, support element references, including dimensions, alignments, and face hosting, as well as snapping. This default behavior can be changed using the DirectShapeOptions.ReferencingOption property. If it is set to NotReferenceable, the geometry may not be used for dimensioning, snapping, alignment, or face-hosting. The element may still be selected by the user for operations which do not reference individual geometry objects.
DirectShape elements also support the ability to participate in room boundary calculations, if they are of an appropriate category for room boundary calculations, and if the associated "Room Bounding" parameter is set to true. The property DirectShapeOptions.RoomBoundingOption identifies whether the DirectShape supports an option for the "Room Bounding" parameter to permit participation in room boundary calculations. The default value is NotApplicable, but this will be changed automatically to SetByParameter for applicable DirectShapes.
## Tagging Direct Shape Geometry
References (such as dimensions) to DirectShape geometry can be maintained when the geometry changes. To do this, add geometry to the DirectShape using the `AddExternallyTaggedGeometry` method. The sample below shows how to create an instance of the `BRepBuilderPersistentIds` class and use `AddSubTag` to build a map of named `ExternalGeometryId`'s and their corresponding `BRepBuilderGeometryId`'s. When the geometry is modified, use `UpdateExternallyTaggedGeometry` and use the same names for the `ExternalGeometryId`'s that you will associate with the new geometry.
The _CreateDirectShape_ sample creates a direct shape with a face named "face1". After running this command, manually create a dimension that references this face. Then run _ModifyDirectShape_ to create a new face in the direct shape. Because the old and new faces are both named "face1", the dimension will survive the operation and reference the new face. If you change the _ModifyDirectShape_ code to give the face a different name, then the dimension will fail regeneration with the error that "One or more dimension references are or have become invalid.".
You can also provide an external tag to reference geometry. There is a change in behavior for the following methods. These methods will associate an external ID with the added reference object, if the `DirectShapeReferenceOptions` specify one. An exception is thrown if the `DirectShape` or `DirectShapeType` already has reference geometry with the specified external ID.
* DirectShape.AddReferencePlane()
* DirectShape.AddReferencePoint()
* DirectShape.AddReferenceCurve()
* DirectShapeType.AddReferencePlane()
* DirectShapeType.AddReferencePoint()
* DirectShapeType.AddReferenceCurve()
public DirectShape CreateDirectShape(Document doc)
{
DirectShape ds;
using (Transaction tr = new Transaction(doc, "Create DirectShape"))
{
tr.Start();
ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.AddExternallyTaggedGeometry(CreateTriangularFace("face1", 1));
tr.Commit();
}
return ds;
}
public void ModifyDirectShape(DirectShape ds)
{
using (Transaction tr = new Transaction(ds.Document, "Update DirectShape"))
{
tr.Start();
ds.UpdateExternallyTaggedGeometry(CreateTriangularFace("face1", 10));
tr.Commit();
}
}
private ExternallyTaggedBRep CreateTriangularFace(string name, double x)
{
BRepBuilder brepBuilder = new BRepBuilder(BRepType.OpenShell);
XYZ pt0 = new XYZ(x, 0, 0);
XYZ pt1 = new XYZ(x, 10, 0);
XYZ pt2 = new XYZ(x, 10, 10);
BRepBuilderGeometryId faceId = brepBuilder.AddFace(BRepBuilderSurfaceGeometry.Create(
Plane.CreateByOriginAndBasis(pt0, XYZ.BasisZ, XYZ.BasisY), null), true);
BRepBuilderGeometryId loopId = brepBuilder.AddLoop(faceId);
brepBuilder.AddCoEdge(loopId, brepBuilder.AddEdge(BRepBuilderEdgeGeometry.Create(pt0, pt1)), false);
brepBuilder.AddCoEdge(loopId, brepBuilder.AddEdge(BRepBuilderEdgeGeometry.Create(pt1, pt2)), false);
brepBuilder.AddCoEdge(loopId, brepBuilder.AddEdge(BRepBuilderEdgeGeometry.Create(pt2, pt0)), false);
brepBuilder.FinishLoop(loopId);
brepBuilder.FinishFace(faceId);
brepBuilder.Finish();
BRepBuilderPersistentIds persistentIds = new BRepBuilderPersistentIds(brepBuilder);
persistentIds.AddSubTag(new ExternalGeometryId(name), faceId);
ExternallyTaggedBRep result = brepBuilder.GetResult(new ExternalGeometryId("MyShape"), persistentIds);
return result;
}
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,103 @@
# About family documents
# About family documents
### Family
The Family object represents an entire Revit family. A Family Document is a Document that represents a Family rather than a Revit project.
Using the Family Creation functionality of the Revit API, you can create and edit families and their types. This functionality is particularly useful when you have pre-existing data available from an external system that you want to convert to a Revit family library.
API access to system family editing is not available.
### Categories
As noted in the previous section, the Family.FamilyCategory property indicates the category of the Family such as Columns, Furniture, Structural Framing, or Windows.
The following code can be used to determine the category of the family in an open Revit Family document.
**Code Region 13-1: Category of open Revit Family Document**
---
public void GetName(Document familyDoc)
{
string categoryName = familyDoc.OwnerFamily.FamilyCategory.Name;
}
The FamilyCategory can also be set, allowing the category of a family that is being edited to be changed.
### Parameters
Family parameters can be accessed from the OwnerFamily property of a Family Document as the following example shows.
**Code Region 13-2: Category of open Revit Family Document**
---
public void GetFamilyDocumentCategory(Document familyDoc)
{
// get the owner family of the family document.
Family family = familyDoc.OwnerFamily;
Parameter param = family.GetParameter(ParameterTypeId.FamilyWorkPlaneBased);
// this param is a Yes/No parameter in UI, but an integer value in API
// 1 for true and 0 for false
int isTrue = param.AsInteger();
// param.Set(1); // set value to true.
}
### Creating a Family Document
The ability to modify Revit Family documents and access family types and parameters is available from the Document class if the Document is a Family document, as determined by the IsFamilyDocument property. To edit an existing family while working in a Project document, use the EditFamily() functions available from the Document class, and then use LoadFamily() to reload the family back into the owner document after editing is complete. To create a new family document use Application.NewFamilyDocument():
**Code Region 13-3: Creating a new Family document**
---
public void CreateFamily(Application application)
{
// create a new family document using Generic Model.rft template
string templateFileName = @"C:\Documents and Settings\All Users\Application Data\Autodesk\RST 2011\Imperial Templates\Generic Model.rft";
Document familyDocument = application.NewFamilyDocument(templateFileName);
if (null == familyDocument)
{
throw new Exception("Cannot open family document");
}
}
### Nested Family Symbols
You can filter a Family Document for FamilySymbols to get all of the FamilySymbols loaded into the Family. In this code sample, all the nested FamilySymbols in the Family for a given FamilyInstance are listed.
**Code Region 13-4: Getting nested Family symbols in a Family**
---
public void GetLoadedSymbols(Autodesk.Revit.DB.Document document, FamilyInstance familyInstance)
{
if (null != familyInstance.Symbol)
{
// Get family associated with this
Family family = familyInstance.Symbol.Family;
// Get Family document for family
Document familyDoc = document.EditFamily(family);
if (null != familyDoc && familyDoc.IsFamilyDocument == true)
{
String loadedFamilies = "FamilySymbols in " + family.Name + ":\n";
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> collection =
collector.OfClass(typeof(FamilySymbol)).ToElements();
foreach (Element e in collection)
{
FamilySymbol fs = e as FamilySymbol;
loadedFamilies += "\t" + fs.Name + "\n";
}
TaskDialog.Show("Revit",loadedFamilies);
}
}
}
**Parent page:** [Family Documents](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_html.html)

View File

@@ -0,0 +1,146 @@
# Create a form element
# Create a form element
The FamilyItemFactory class provides the ability to create form elements in families, such as extrusions, revolutions, sweeps, and blends. See the section on [3D Sketch](../../Sketching/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_3D_Sketch_html.html) for more information on these 3D sketch forms.
The following example demonstrates how to create a new Extrusion element. It creates a simple rectangular profile and then moves the newly created Extrusion to a new location.
**Code Region: Creating a new Extrusion**
---
private Extrusion CreateExtrusion(Autodesk.Revit.DB.Document document, SketchPlane sketchPlane)
{
Extrusion rectExtrusion = null;
// make sure we have a family document
if (true == document.IsFamilyDocument)
{
// define the profile for the extrusion
CurveArrArray curveArrArray = new CurveArrArray();
CurveArray curveArray1 = new CurveArray();
CurveArray curveArray2 = new CurveArray();
CurveArray curveArray3 = new CurveArray();
// create a rectangular profile
XYZ p0 = XYZ.Zero;
XYZ p1 = new XYZ(10, 0, 0);
XYZ p2 = new XYZ(10, 10, 0);
XYZ p3 = new XYZ(0, 10, 0);
Line line1 = Line.CreateBound(p0, p1);
Line line2 = Line.CreateBound(p1, p2);
Line line3 = Line.CreateBound(p2, p3);
Line line4 = Line.CreateBound(p3, p0);
curveArray1.Append(line1);
curveArray1.Append(line2);
curveArray1.Append(line3);
curveArray1.Append(line4);
curveArrArray.Append(curveArray1);
// create solid rectangular extrusion
rectExtrusion = document.FamilyCreate.NewExtrusion(true, curveArrArray, sketchPlane, 10);
if (null != rectExtrusion)
{
// move extrusion to proper place
XYZ transPoint1 = new XYZ(-16, 0, 0);
ElementTransformUtils.MoveElement(document, rectExtrusion.Id, transPoint1);
}
else
{
throw new Exception("Create new Extrusion failed.");
}
}
else
{
throw new Exception("Please open a Family document before invoking this command.");
}
return rectExtrusion;
}
The following sample shows how to create a new Sweep from a solid ovoid profile in a Family Document. **Code Region: Creating a new Sweep**
---
private Sweep CreateSweep(Autodesk.Revit.DB.Document document, SketchPlane sketchPlane)
{
Sweep sweep = null;
// make sure we have a family document
if (true == document.IsFamilyDocument)
{
// Define a profile for the sweep
CurveArrArray arrarr = new CurveArrArray();
CurveArray arr = new CurveArray();
// Create an ovoid profile
XYZ pnt1 = new XYZ(0, 0, 0);
XYZ pnt2 = new XYZ(2, 0, 0);
XYZ pnt3 = new XYZ(1, 1, 0);
arr.Append(Arc.Create(pnt2, 1.0d, 0.0d, 180.0d, XYZ.BasisX, XYZ.BasisY));
arr.Append(Arc.Create(pnt1, pnt3, pnt2));
arrarr.Append(arr);
SweepProfile profile = document.Application.Create.NewCurveLoopsProfile(arrarr);
// Create a path for the sweep
XYZ pnt4 = new XYZ(10, 0, 0);
XYZ pnt5 = new XYZ(0, 10, 0);
Curve curve = Line.CreateBound(pnt4, pnt5);
CurveArray curves = new CurveArray();
curves.Append(curve);
// create a solid ovoid sweep
sweep = document.FamilyCreate.NewSweep(true, curves, sketchPlane, profile, 0, ProfilePlaneLocation.Start);
if (null != sweep)
{
// move to proper place
XYZ transPoint1 = new XYZ(11, 0, 0);
ElementTransformUtils.MoveElement(document, sweep.Id, transPoint1);
}
else
{
throw new Exception("Failed to create a new Sweep.");
}
}
else
{
throw new Exception("Please open a Family document before invoking this command.");
}
return sweep;
}
**Figure 50: Ovoid sweep created by previous example**
The FreeFormElement class allows for the creation of non-parametric geometry created from an input solid outline. A FreeFormElement can participate in joins and void cuts with other combinable elements. Planar faces of the element can be offset interactively and programmatically in the face normal direction.
### Assigning Subcategories to forms
After creating a new form in a family, you may want to change the subcategory for the form. For example, you may have a Door family and want to create multiple subcategories of doors and assign different subcategories to different door types in your family.
The following example shows how to create a new subcategory, assign it a material, and then assign the subcategory to a form.
**Code Region: Assigning a subcategory**
---
public void AssignSubCategory(Document document, GenericForm extrusion)
{
// create a new subcategory
Category cat = document.OwnerFamily.FamilyCategory;
Category subCat = document.Settings.Categories.NewSubcategory(cat, "NewSubCat");
// create a new material and assign it to the subcategory
ElementId materialId = Material.Create(document, "Wood Material");
subCat.Material = document.GetElement(materialId) as Material;
// assign the subcategory to the element
extrusion.Subcategory = subCat;
}
**Parent page:** [Creating elements in families](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Creating_elements_in_families_html.html)

View File

@@ -0,0 +1,89 @@
# Create an annotation
# Create an annotation
New annotations such as Dimensions and ModelText and TextNote objects can also be created in families, as well as curve annotation elements such as SymbolicCurve, ModelCurve, and DetailCurve. See [Annotation Elements](../../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Annotation_Elements_html.html) for more information on Annotation elements.
Additionally, a new Alignment can be added, referencing a View that determines the orientation of the alignment, and two geometry references.
The following example demonstrates how to create a new arc length Dimension.
**Code Region: Creating a Dimension**
---
public Dimension CreateArcDimension(Document document, SketchPlane sketchPlane)
{
Autodesk.Revit.Creation.Application appCreate = document.Application.Create;
Line gLine1 = Line.CreateBound(new XYZ(0, 2, 0), new XYZ(2, 2, 0));
Line gLine2 = Line.CreateBound(new XYZ(0, 2, 0), new XYZ(2, 4, 0));
Arc arctoDim = Arc.Create(new XYZ(1, 2, 0), new XYZ(-1, 2, 0), new XYZ(0, 3, 0));
Arc arcofDim = Arc.Create(new XYZ(0, 3, 0), new XYZ(1, 2, 0), new XYZ(0.8, 2.8, 0));
Autodesk.Revit.Creation.FamilyItemFactory creationFamily = document.FamilyCreate;
ModelCurve modelCurve1 = creationFamily.NewModelCurve(gLine1, sketchPlane);
ModelCurve modelCurve2 = creationFamily.NewModelCurve(gLine2, sketchPlane);
ModelCurve modelCurve3 = creationFamily.NewModelCurve(arctoDim, sketchPlane);
//get their reference
Reference ref1 = modelCurve1.GeometryCurve.Reference;
Reference ref2 = modelCurve2.GeometryCurve.Reference;
Reference arcRef = modelCurve3.GeometryCurve.Reference;
Dimension newArcDim = creationFamily.NewArcLengthDimension(document.ActiveView, arcofDim, arcRef, ref1, ref2);
if (newArcDim == null)
{
throw new Exception("Failed to create new arc length dimension.");
}
return newArcDim;
}
**Figure 51: Resulting arc length dimension**
Some types of dimensions can be labeled with a FamilyParameter. Dimensions that cannot be labeled will throw an Autodesk.Revit.Exceptions.InvalidOperationException if you try to get or set the Label property. In the following example, a new linear dimension is created between two lines and labeled as "width".
**Code Region: Labeling a dimension**
---
public Dimension CreateLinearDimension(Document document)
{
// first create two lines
XYZ pt1 = new XYZ(5, 5, 0);
XYZ pt2 = new XYZ(5, 10, 0);
Line line = Line.CreateBound(pt1, pt2);
Plane plane = Plane.CreateByNormalAndOrigin(pt1.CrossProduct(pt2), pt2);
SketchPlane skplane = SketchPlane.Create (document, plane);
ModelCurve modelcurve1 = document.FamilyCreate.NewModelCurve(line, skplane);
pt1 = new XYZ(10, 5, 0);
pt2 = new XYZ(10, 10, 0);
line = Line.CreateBound(pt1, pt2);
plane = Plane.CreateByNormalAndOrigin(pt1.CrossProduct(pt2), pt2);
skplane = SketchPlane.Create (document, plane);
ModelCurve modelcurve2 = document.FamilyCreate.NewModelCurve(line, skplane);
// now create a linear dimension between them
ReferenceArray ra = new ReferenceArray();
ra.Append(modelcurve1.GeometryCurve.Reference);
ra.Append(modelcurve2.GeometryCurve.Reference);
pt1 = new XYZ(5, 10, 0);
pt2 = new XYZ(10, 10, 0);
line = Line.CreateBound(pt1, pt2);
Dimension dim = document.FamilyCreate.NewLinearDimension(document.ActiveView, line, ra);
// create a label for the dimension called "width"
FamilyParameter param = document.FamilyManager.AddParameter("width",
GroupTypeId.Constraints,
SpecTypeId.Length, false);
dim.FamilyLabel = param;
return dim;
}
**Figure 52: Labeled linear dimension**
**Parent page:** [Creating elements in families](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Creating_elements_in_families_html.html)

View File

@@ -0,0 +1,14 @@
# Creating elements in families
# Creating elements in families
The FamilyItemFactory class provides the ability to create elements in family documents. It is accessed through the Document.FamilyCreate property. FamilyItemFactory is derived from the ItemFactoryBase class which is a utility to create elements in both Revit project documents and family documents.
**Pages in this section**
* [Create a form element](Creating_elements_in_families/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Creating_elements_in_families_Create_a_form_element_html.html)
* [Create an annotation](Creating_elements_in_families/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Creating_elements_in_families_Create_an_annotation_html.html)
**Parent page:** [Family Documents](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_html.html)

View File

@@ -0,0 +1,187 @@
# Managing family types and parameters
# Managing family types and parameters
Family documents provide access to the FamilyManager property. The FamilyManager class provides access to family types and parameters. Using this class you can add and remove types, add and remove family and shared parameters, set the value for parameters in different family types, and define formulas to drive parameter values.
### Getting Types in a Family
The FamilyManager can be used to iterate through the types in a family, as the following example demonstrates.
**Code Region 13-11: Getting the types in a family**
---
public void GetFamilyTypesInFamily(Document familyDoc)
{
if (familyDoc.IsFamilyDocument)
{
FamilyManager familyManager = familyDoc.FamilyManager;
// get types in family
string types = "Family Types: ";
FamilyTypeSet familyTypes = familyManager.Types;
FamilyTypeSetIterator familyTypesItor = familyTypes.ForwardIterator();
familyTypesItor.Reset();
while (familyTypesItor.MoveNext())
{
FamilyType familyType = familyTypesItor.Current as FamilyType;
types += "\n" + familyType.Name;
}
TaskDialog.Show("Revit",types);
}
}
**Figure 53: Family types in Concrete-Rectangular-Column family**
### Editing FamilyTypes
FamilyManager provides the ability to iterate through existing types in a family, and add and modify types and their parameters.
The following example shows how to add a new type, set its parameters and then assign the new type to a FamilyInstance. Type editing is done on the current type by using the Set() function. The current type is available from the CurrentType property. The CurrentType property can be used to set the current type before editing, or use the NewType() function which creates a new type and sets it to the current type for editing.
Note that once the new type is created and modified, Document.LoadFamily() is used to load the family back into the Revit project to make the new type available.
**Code Region 13-12: Editing Family Types**
---
public void EditFamilyTypes(Document document, FamilyInstance familyInstance)
{
// example works best when familyInstance is a rectangular concrete element
if ((null == document) || (null == familyInstance.Symbol))
{
return; // invalid arguments
}
// Get family associated with this
Family family = familyInstance.Symbol.Family;
if (null == family)
{
return; // could not get the family
}
// Get Family document for family
Document familyDoc = document.EditFamily(family);
if (null == familyDoc)
{
return; // could not open a family for edit
}
FamilyManager familyManager = familyDoc.FamilyManager;
if (null == familyManager)
{
return; // cuould not get a family manager
}
// Start transaction for the family document
using (Transaction newFamilyTypeTransaction = new Transaction(familyDoc, "Add Type to Family"))
{
int changesMade = 0;
newFamilyTypeTransaction.Start();
// add a new type and edit its parameters
FamilyType newFamilyType = familyManager.NewType("2X2");
if (newFamilyType != null)
{
// look for 'b' and 'h' parameters and set them to 2 feet
FamilyParameter familyParam = familyManager.get_Parameter("b");
if (null != familyParam)
{
familyManager.Set(familyParam, 2.0);
changesMade += 1;
}
familyParam = familyManager.get_Parameter("h");
if (null != familyParam)
{
familyManager.Set(familyParam, 2.0);
changesMade += 1;
}
}
if (2 == changesMade) // set both paramaters?
{
newFamilyTypeTransaction.Commit();
}
else // could not make the change -> should roll back
{
newFamilyTypeTransaction.RollBack();
}
// if could not make the change or could not commit it, we return
if (newFamilyTypeTransaction.GetStatus() != TransactionStatus.Committed)
{
return;
}
}
// now update the Revit project with Family which has a new type
LoadOpts loadOptions = new LoadOpts();
// This overload is necessary for reloading an edited family
// back into the source document from which it was extracted
family = familyDoc.LoadFamily(document, loadOptions);
if (null != family)
{
// find the new type and assign it to FamilyInstance
ISet<ElementId> familySymbolIds = family.GetFamilySymbolIds();
foreach (ElementId id in familySymbolIds)
{
FamilySymbol familySymbol = family.Document.GetElement(id) as FamilySymbol;
if ((null != familySymbol) && familySymbol.Name == "2X2")
{
using (Transaction changeSymbol = new Transaction(document, "Change Symbol Assignment"))
{
changeSymbol.Start();
familyInstance.Symbol = familySymbol;
changeSymbol.Commit();
}
break;
}
}
}
}
class LoadOpts : IFamilyLoadOptions
{
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}
public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = true;
return true;
}
}
The FamilyManager class provides access to all the family parameters. This includes family built-in parameters, category built-in parameters and shared parameters associated to the family types. There are two ways to get the family parameters:
* Parameters property - gets all parameters in the family
* GetParameters() - gets all the parameters in the family in order in which they appear in the Revit UI When using the GetParameters() method, the Revit UI order is determined first by group and next by the order of the individual parameters.
Family parameters can be reordered (within their groups) from the API for a given family (with the exception of the Rebar Shape family which does not support reordering parameters). This allows for parameters to be presented to the user in the most logical order. Sorting only affects visible parameters within the same parameter group. Parameters that belong to different groups will remain separated, and the groups' order will not be affected.
The simplest way to reorder parameters is using the FamilyManager.SortParameters() method, which takes a parameter indicating the desired sort order. The sample below sorts the parameters in ascending order. Code Region: Sort family parameters
---
private void DisplayParametersInAscendingOrder(Document familyDoc)
{
FamilyManager familyManager = familyDoc.FamilyManager;
familyManager.SortParameters(ParametersOrder.Ascending);
}
Note: The sort is a one-time operation. When new parameters are added they will not be automatically sorted.
For more control over how parameters are sorted, use the FamilyManager.ReorderParameters() method which takes a list of family parameters in the new order. This list must include all the parameters returned by the GetParameters() method, including any invisible parameters, or an exception will be thrown.
**Parent page:** [Family Documents](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_html.html)

View File

@@ -0,0 +1,54 @@
# Visibility of family elements
# Visibility of family elements
The FamilyElementVisibility class can be used to control the visibility of family elements in the project document. For example, if you have a door family, you may only want the door swing to be visible in plan views in the project document in which doors are placed, not 3D views. By setting the visibility on the curves of the door swing, you can control their visibility. FamilyElementVisibility is applicable to the following family element classes which have the SetVisibility() function:
* GenericForm, which is the base class for form classes such as Sweep and Extrusion
* SymbolicCurve
* ModelText
* CurveByPoints
* ModelCurve
* ReferencePoint
* ImportInstance
In the example below, the resulting family document will display the text "Hello World" with a line under it. When the family is loaded into a Revit project document and an instance is placed, in plan view, only the line will be visible. In 3D view, both the line and text will be displayed, unless the Detail Level is set to Course, in which case the line will disappear.
**Code Region 13-10: Setting family element visibility**
---
public void CreateAndSetVisibility(Autodesk.Revit.DB.Document familyDocument, SketchPlane sketchPlane)
{
// create a new ModelCurve in the family document
XYZ p0 = new XYZ(1, 1, 0);
XYZ p1 = new XYZ(5, 1, 0);
Line line1 = Line.CreateBound(p0, p1);
ModelCurve modelCurve1 = familyDocument.FamilyCreate.NewModelCurve(line1, sketchPlane);
// create a new ModelText along ModelCurve line
ModelText text = familyDocument.FamilyCreate.NewModelText("Hello World", null, sketchPlane, p0, HorizontalAlign.Center, 0.1);
// set visibility for text
FamilyElementVisibility textVisibility = new FamilyElementVisibility(FamilyElementVisibilityType.Model);
textVisibility.IsShownInTopBottom = false;
text.SetVisibility(textVisibility);
// set visibility for line
FamilyElementVisibility curveVisibility = new FamilyElementVisibility(FamilyElementVisibilityType.Model);
curveVisibility.IsShownInCoarse = false;
modelCurve1.SetVisibility(curveVisibility);
}
**Parent page:** [Family Documents](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_html.html)

View File

@@ -0,0 +1,21 @@
# Family Documents
# Family Documents
This section discusses families and how to:
* Create and modify Family documents
* Access family types and parameters
**Pages in this section**
* [About family documents](Family_Documents/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_About_family_documents_html.html)
* [Creating elements in families](Family_Documents/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Creating_elements_in_families_html.html)
* [Visibility of family elements](Family_Documents/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Visibility_of_family_elements_html.html)
* [Managing family types and parameters](Family_Documents/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Documents_Managing_family_types_and_parameters_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,190 @@
# Code Samples
# Code Samples
Review the following code samples for more information about working with Family Instances. Please note that in the NewFamilyInstance() method, a StructuralType argument is required to specify the type of the family instance to be created. Here are some examples:
**Table 34: The value of StructuralType argument in the NewFamilyInstance() method**
**Type of Family Instance** | **Value of StructuralType**
---|---
Doors, tables, etc. | NonStructural
Beams | Beam
Braces | Brace
Columns | Column
Footings | Footing
### Create Tables
The following function demonstrates how to load a family of Tables into a Revit project and create instances from all symbols in this family.
The LoadFamily() method returns false if the specified family was previously loaded. Therefore, in the following case, do not load the family, Table-Dining Round w Chairs.rfa, before this function is called. In this example, the tables are created at Level 1 by default.
**Code Region 12-3: Creating tables**
---
void CreateTables(Autodesk.Revit.DB.Document document)
{
String fileName = @"C:\ProgramData\Autodesk\RVT 2014\Libraries\US Imperial\Furniture\Tables\Table-Dining Round w Chairs.rfa";
// try to load family
Family family = null;
if (!document.LoadFamily(fileName, out family))
{
throw new Exception("Unable to load " + fileName);
}
// Loop through table symbols and add a new table for each
ISet<ElementId> familySymbolIds = family.GetFamilySymbolIds();
double x = 0.0, y = 0.0;
foreach (ElementId id in familySymbolIds)
{
FamilySymbol symbol = family.Document.GetElement(id) as FamilySymbol;
XYZ location = new XYZ(x, y, 10.0);
FamilyInstance instance = document.Create.NewFamilyInstance(location, symbol, StructuralType.NonStructural);
x += 10.0;
}
}
The result of loading the Tables family and placing one instance of each FamilySymbol:
**Figure 47: Load family and create tables in the Revit project**
### Create a Beam
In this sample, a family symbol is loaded instead of a family, because loading a single FamilySymbol is faster than loading a Family that contains many FamilySymbols.
**Code Region 12-4: Creating a beam**
---
FamilyInstance CreateBeam(Autodesk.Revit.DB.Document document, View view)
{
// get the given view's level for beam creation
Level level = document.GetElement(view.LevelId) as Level;
// get a family symbol
FilteredElementCollector collector = new FilteredElementCollector(document);
collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralFraming);
FamilySymbol gotSymbol = collector.FirstElement() as FamilySymbol;
// create new beam 10' long starting at origin
XYZ startPoint = new XYZ(0, 0, 0);
XYZ endPoint = new Autodesk.Revit.DB.XYZ(10, 0, 0);
Autodesk.Revit.DB.Curve beamLine = Line.CreateBound(startPoint, endPoint);
// create a new beam
FamilyInstance instance = document.Create.NewFamilyInstance(beamLine, gotSymbol, level, StructuralType.Beam);
return instance;
}
### Create Doors
Create a long wall about 180' in length and select it before running this sample. The host object must support inserting instances; otherwise the NewFamilyInstance() method will fail. If a host element is not provided for an instance that must be created in a host, or the instance cannot be inserted into the specified host element, the method NewFamilyInstance() does nothing.
**Code Region 12-5: Creating doors**
---
void CreateDoorsInWall(Autodesk.Revit.DB.Document document, Wall wall)
{
// get wall's level for door creation
Level level = document.GetElement(wall.LevelId) as Level;
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol))
.OfCategory(BuiltInCategory.OST_Doors)
.ToElements();
IEnumerator<Element> symbolItor = collection.GetEnumerator();
double x = 0, y = 0, z = 0;
while (symbolItor.MoveNext())
{
FamilySymbol symbol = symbolItor.Current as FamilySymbol;
XYZ location = new XYZ(x, y, z);
FamilyInstance instance = document.Create.NewFamilyInstance(location, symbol, wall, level, StructuralType.NonStructural);
x += 10;
y += 10;
z += 1.5;
}
}
The result of the previous code in Revit is shown in the following picture. Notice that if the specified location is not at the specified level, the NewFamilyInstance() method uses the location elevation instead of the level elevation.
**Figure 48: Insert doors into a wall**
### Create FamilyInstances Using Reference Directions
Use reference directions to insert an item in a specific direction.
**Code Region 12-6: Creating FamilyInstances using reference directions**
---
public void CreateWithRefDir(Document document)
{
// Get a floor to place the beds
FilteredElementCollector collector = new FilteredElementCollector(document);
Floor floor = collector.OfClass(typeof(Floor)).FirstElement() as Floor;
if (floor != null)
{
// Find a Bed-Box family
Family family = null;
FilteredElementCollector famCollector = new FilteredElementCollector(document);
famCollector.OfClass(typeof(Family));
ICollection<Element> collection = famCollector.ToElements();
foreach (Element element in collection)
{
if (element.Name.CompareTo("Bed-Box") == 0)
{
family = element as Family;
break;
}
}
if (family != null)
{
// Enumerate the beds in the Bed-Box family
FilteredElementCollector fsCollector = new FilteredElementCollector(document);
ICollection<Element> fsCollection = fsCollector.WherePasses(new FamilySymbolFilter(family.Id)).ToElements();
IEnumerator<Element> symbolItor = fsCollection.GetEnumerator();
int x = 0, y = 0;
int i = 0;
while (symbolItor.MoveNext())
{
FamilySymbol symbol = symbolItor.Current as FamilySymbol;
XYZ location = new XYZ(x, y, 0);
XYZ direction = new XYZ();
switch (i % 3)
{
case 0:
direction = new XYZ(1, 1, 0);
break;
case 1:
direction = new XYZ(0, 1, 1);
break;
case 2:
direction = new XYZ(1, 0, 1);
break;
}
FamilyInstance instance = document.Create.NewFamilyInstance(location, symbol, direction, floor, StructuralType.NonStructural);
x += 10;
i++;
}
}
}
}
The result of the previous code appears in the following picture:
**Figure 49: Create family instances using different reference directions**
**Parent page:** [Family Instances](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_html.html)

View File

@@ -0,0 +1,261 @@
# FamilyInstances
# FamilyInstances
FamilyInstance objects include Beams, Braces, Columns, Furniture, Massing, and more. The FamilyInstance object provides more detailed properties so that the family instance type and appearance in the project can be changed.
### Location-Related Properties
Location-related properties show the physical and geometric characteristics of FamilyInstance objects, such as orientation, rotation and location.
#### Orientation
The face orientation or hand orientation can be changed for some FamilyInstance objects. For example, a door can face the outside or the inside of a room or wall and it can be placed with the handle on the left side or the right side. The following table compares door, window, and desk family instances.
**Table 29: Compare Family Instances**
**Boolean Property** | **Door** | **Window (Fixed: 36"w × 72"h)** | **Desk**
---|---|---|---
CanFlipFacing | True | True | False
CanFlipHand | True | False | False
If CanFlipFacing or CanFlipHand is true, you can call the flipFacing() or flipHand() methods respectively. These methods can change the facing orientation or hand orientation respectively. Otherwise, the methods do nothing and return False.
When changing orientation, remember that some types of windows can change both hand orientation and facing orientation, such as a Casement 3x3 with Trim family.
There are four different facing orientation and hand orientation combinations for doors. See the following picture for the combinations and the corresponding Boolean values are in the following table.
**Figure 44: Doors with different Facing and Hand Orientations**
**Table 30: Different Instances of the Same Type**
**Boolean Property** | **Door 1** | **Door 2** | **Door 3** | **Door 4**
---|---|---|---|---
FacingFlipped | False | True | False | True
HandFlipped | False | True | True | False
#### Orientation - Work Plane
The work plane orientation for a FamilyInstance can be changed, as well. If CanFlipWorkPlane is true, you can set the IsWorkPlaneFlipped property. Attempting to set this property for a FamilyInstance that does not allow the work plane to be flipped will result in an exception.
#### Rotation - Mirrored
The Mirrored property indicates whether the FamilyInstance object has been mirrored.
**Table 31: Door Mirrored Property**
**Boolean Property** | **Door 1** | **Door 2** | **Door 3** | **Door 4**
---|---|---|---|---
Mirrored | False | False | True | True
In the previous door example, the Mirrored property for Door 1 and Door 2 is False, while for both Door 3 and Door 4 it is True. This is because when you create a door in the Revit project, the default result is either Door 1 or Door 2. To create a door like Door 3 or Door 4, you must flip the Door 1 and Door 2 hand orientation respectively. The flip operation is like a mirror transformation, which is why the Door 3 and Door 4 Mirrored property is True.
For more information about using the Mirror() method in Revit, refer to the [Editing Elements](../../Basic_Interaction_with_Revit_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html) chapter.
#### Rotation - CanRotate and rotate()
The family instance Boolean CanRotate property is used to test whether the family instance can be rotated 180 degrees. This depends on the family to which the instance belongs. For example, in the following picture, the CanRotate properties for Window 1 (Casement 3×3 with Trim: 36"×72") and Door 1 (Double-Glass 2: 72"×82") are true, while Window 2 (Fixed: 36"w × 72"h) is false.
**Figure 45: Changes after rotate()**
If CanRotate is true, you can call the family instance rotate() method, which flips the family instance by 180 degrees. Otherwise, the method does nothing and returns False. The previous picture also shows the Window 1 and Door 1 states after executing the rotate() method.
Recall from the [Rotating elements](../../Basic_Interaction_with_Revit_Elements/Editing_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_Rotating_elements_html.html) section earlier in this document, that family instances (and other elements) can be rotated a user-specified angle usingElementTransformUtils.RotateElement() and ElementTransformUtils.RotateElements().
#### Location
The Location property determines the physical location of an instance in a project. An instance can have a point location or a line location.
The following characteristics apply to Location:
* A point location is a LocationPoint class object - A footing, a door, or a table has a point location.
* A line location is a LocationCurve class object - A beam has a line location.
* They are both subclasses of the Location class.
For more information about Location, refer to [Editing Elements](../../Basic_Interaction_with_Revit_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html).
### Host and HostFace
Host and HostFace are both FamilyInstance properties.
#### Host
A FamilyInstance object has a Host property that returns its hosting element.
Some FamilyInstance objects do not have host elements, such as Tables and other furniture, so the Host property returns nothing because no host elements are created. However, other objects, such as doors and windows, must have host elements. In this case the Host property returns a wall Element in which the window or the door is located. See the following picture.
**Figure 46: Doors and windows hosted in a wall**
HostFace The HostFace property gets the reference to the host face of the family instance, or if the instance is placed on a work plane, the reference to the geometry face underlying the work plane. This property will return a null reference if the work plane is not referencing other geometry, or if the instance is not hosted on a face or work plane.
### Subcomponent and Supercomponent
The FamilyInstance.GetSubComponentIds() method returns the ElementIds of family instances loaded into that family. When an instance of 'Table-Dining Round w Chairs.rfa' is placed in a project, the ElementIds of the set of chairs are returned by the GetSubComponentIds() method.
The SuperComponent property returns the family instance's parent component. In 'Table-Dining Round w Chairs.rfa', the family instance supercomponent for each nested chair is the instance of 'Table-Dining Round w Chairs.rfa'.
**Code Region 12-1: Getting SubComponents and SuperComponent from FamilyInstance**
---
public void GetSubAndSuperComponents(FamilyInstance familyInstance)
{
ICollection<ElementId> subElemSet = familyInstance.GetSubComponentIds();
if (subElemSet != null)
{
string subElems = "";
foreach (Autodesk.Revit.DB.ElementId ee in subElemSet)
{
FamilyInstance f = familyInstance.Document.GetElement(ee) as FamilyInstance;
subElems = subElems + f.Name + "\n";
}
TaskDialog.Show("Revit","Subcomponent count = " + subElemSet.Count + "\n" + subElems);
}
FamilyInstance super = familyInstance.SuperComponent as FamilyInstance;
if (super != null)
{
TaskDialog.Show("Revit","SUPER component: " + super.Name);
}
}
### Geometry
Sometimes the geometry of a FamilyInstance object is modified by joins, cuts, coping, extensions, or other post-processing that occurs in Revit. The FamilyInstance.HasModifiedGeometry() method identifies if the geometry of this FamilyInstance has been modified from the automatically generated default. The GetOriginalGeometry() method will return the original geometry of the instance prior to any modifications that may have occurred. To get the current geometry of the instance, use the Geometry property inherited from the Element class.
### Spatial Element Calculation Points
The FamilyInstance has several members for reading the information about spatial calculation point(s) directly from the family instance. The HasSpatialElementCalculationPoint property identifies if this instance has a single SpatialElementCalculationPoint used as the search point for Revit to identify if the instance is inside a room or space. If true, the GetSpatialElementCalculationPoint() method will return the location of the calculation point for this instance as an XYZ point.
The HasSpatialElementFromToCalculationPoints property identifies if this instance has a pair of SpatialElementCalculationPoints used as the search points for Revit to identify if the instance lies between up to two rooms or spaces. The points determine which room or space is considered the "from" and which is considered the "to" for a family instance which connects two rooms or spaces, such as a door or window. When this property is true, the GetSpatialElementFromToCalculationPoints() method returns the locations for the calculation points for this instance as a list of XYZ points.
### Other Properties
The properties in this section are specific to the architectural and structural engineering features of Revit. They are covered thoroughly in their respective chapters.
#### Room Information
FamilyInstance properties include Room, FromRoom, and ToRoom. For more information about Room, refer to [Architecture](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Architecture_html.html).
#### Space Information
FamilyInstance has a Space property for identifying the space that holds an instance in MEP.
#### Structural Analytical Model
The GetAnalyticalModel() method retrieves the family instance structural analytical model.
For more information about AnalyticalModel refer to [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html).
### Creating FamilyInstance Objects
Typically a FamilyInstance object is created using one of the twelve overload methods of Autodesk.Revit.Creation.Document called NewFamilyInstance(). The choice of which overload to use depends not only on the category of the instance, but also other characteristics of the placement like whether it should be hosted, placed relative to a reference level, or placed directly on a particular face. The details are included in Table 32 - Options for creating instance with NewFamilyInstance() below.
Some FamilyInstance objects require more than one location to be created. In these cases, it is more appropriate to use the more detailed creation method provided by this object (see Table 33 - Options for creating instances with other methods below). If the instance is not created, an exception is thrown. The type/symbol used must be loaded into the project before the method is called.
All overloads for NewFamilyInstance() check to ensure that the input FamilySymbol is active (FamilySymbol.IsActive). If the input FamilySymbol is inactive, the method will throw an ArgumentException. Symbols that are not used in the document may be deactivated to conserve memory and regeneration time. When the symbol is inactive, its geometry is empty and cannot be accessed. In order to access the geometry of a symbol that is not active in the document, the symbol should first be activated by calling FamilySymbol.Activate().
**Table 32 - Options for creating instance with NewFamilyInstance()**
Category | NewFamilyInstance() parameters | Comments
---|---|---
Air Terminals Boundary Conditions Casework Communication Devices Data Devices Electrical Equipment Electrical Fixtures Entourage Fire Alarm Devices Furniture Furniture Systems Generic Models Lighting Devices Lighting Fixtures Mass Mechanical Equipment Nurse Call Devices Parking Planting Plumbing Fixtures Security Devices Site Specialty Equipment Sprinklers Structural Connections Structural Foundations Structural Stiffeners Telephone Devices | XYZ, FamilySymbol, StructuralType | Creates the instance in an arbitrary location without reference to a level or host element.
XYZ, FamilySymbol, Element, StructuralType | If it is to be hosted on a wall, floor or ceiling
XYZ, FamilySymbol, XYZ, Element, StructuralType | If it is to be hosted on a wall, floor, or ceiling, and needs to be oriented in a non-default direction
XYZ, FamilySymbol, Element, Level, StructuralType | If it is to be hosted on a wall, floor or ceiling and associated to a reference level
XYZ, FamilySymbol, Level, StructuralType | If it is to be associated to a reference level
Face, XYZ, XYZ, FamilySymbol | If it is face-based and needs to be oriented in a non-default direction
Reference, XYZ, XYZ, FamilySymbol | If it is face-based and needs to be oriented in a non-default direction, accepts a reference to a face rather than a Face
Face, Line, FamilySymbol | If it is face-based and linear
Reference, Line, FamilySymbol | If it is face-based and linear, but accepts a reference to a face, rather than a Face
Columns Structural Columns | XYZ, FamilySymbol, Level, StructuralType | Creates the column so that its base lies on the reference level. The column will extend to the next available level in the model, or will extend the default column height if there are no suitable levels above the reference level.
Doors Windows | XYZ, FamilySymbol, Element, StructuralType | Doors and windows must be hosted by a wall. Use this method if they can be placed with the default orientation.
XYZ, FamilySymbol, XYZ, Element, StructuralType | If the created instance needs to be oriented in a non-default direction
XYZ, FamilySymbol, Element, Level, StructuralType | If the instance needs to be associated to a reference level
Structural Framing (Beams, Braces) | Curve, FamilySymbol, Level, StructuralType | Creates a level based brace or beam given its curve. This is the recommended method to create Beams and Braces
XYZ, FamilySymbol, StructuralType | Creates instance in an arbitrary location1
XYZ, FamilySymbol, Element, Level, StructuralType | If it is hosted on an element (floor etc.) and associated to a reference level1
XYZ, FamilySymbol, Level, StructuralType | If it is associated to a reference level1
XYZ, FamilySymbol, Element, StructuralType | If it is hosted on an element (floor etc.)1
Detail Component | Line, FamilySymbol, View | Applies only to 2D family line based detail symbols
Generic Annotations | XYZ, FamilySymbol, View | Applies only to 2D family symbols
1 The structural instance will be of zero-length after creation. Extend it by setting its curve (FamilyInstance.Location as LocationCurve) using LocationCurve.Curve property.
You can simplify your code and improve performance by creating more than one family instance at a time using Document.NewFamilyInstances(). This method has a single parameter, which is a list of FamilyInstanceCreationData objects describing the family instances to create.
**Code Region 12-2: Batch creating family instances**
---
ICollection<ElementId> BatchCreateColumns(Autodesk.Revit.DB.Document document, Level level)
{
List<Autodesk.Revit.Creation.FamilyInstanceCreationData> fiCreationDatas = new List<Autodesk.Revit.Creation.FamilyInstanceCreationData>();
ICollection<ElementId> elementSet = null;
//Try to get a FamilySymbol
FamilySymbol familySymbol = null;
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();
foreach (Element e in collection)
{
familySymbol = e as FamilySymbol;
if (null != familySymbol.Category)
{
if ("Structural Columns" == familySymbol.Category.Name)
{
break;
}
}
}
if (null != familySymbol)
{
//Create 10 FamilyInstanceCreationData items for batch creation
for (int i = 1; i < 11; i++)
{
XYZ location = new XYZ(i * 10, 100, 0);
Autodesk.Revit.Creation.FamilyInstanceCreationData fiCreationData = new Autodesk.Revit.Creation.FamilyInstanceCreationData(location, familySymbol, level,
StructuralType.Column);
if (null != fiCreationData)
{
fiCreationDatas.Add(fiCreationData);
}
}
if (fiCreationDatas.Count > 0)
{
// Create Columns
elementSet = document.Create.NewFamilyInstances2(fiCreationDatas);
}
else
{
throw new Exception("Batch creation failed.");
}
}
else
{
throw new Exception("No column types found.");
}
return elementSet;
}
Instances of some family types are better created through methods other than Autodesk.Revit.Creation.Document.NewFamilyInstance(). These are listed in the table below.
**Table 33 - Options for creating instances with other methods**
**Category** | **Creation method** | **Comments**
---|---|---
Air Terminal Tags Area Load Tags Area Tags Casework Tags Ceiling Tags Communication Device Tags Curtain Panel Tags Data Device Tags Detail Item Tags Door Tags Duct Accessory Tags Duct Fitting Tags Duct Tags Electrical Equipment Tags Electrical Fixture Tags Fire Alarm Device Tags Flex Duct Tags Flex Pipe Tags Floor Tags Furniture System Tags Furniture Tags Generic Model Tags Internal Area Load Tags Internal Line Load Tags Internal Point Load Tags Keynote Tags Lighting Device Tags Lighting Fixture Tags Line Load Tags Mass Floor Tags Mass Tags Mechanical Equipment Tags Nurse Call Device Tags Parking Tags Pipe Accessory Tags Pipe Fitting Tags Pipe Tags Planting Tags Plumbing Fixture Tags Point Load Tags Property Line Segment Tags Property Tags Railing Tags Revision Cloud Tags Roof Tags Room Tags Security Device Tags Site Tags Space Tags Specialty Equipment Tags Spinkler Tags Stair Tags Structural Area Reinforcement Tags Structural Beam System Tags Structural Column Tags Structural Connection Tags Structural Foundation Tags Structural Framing Tags Structural Path Reinforcement Tags Structural Rebar Tags Structural Stiffener Tags Structural Truss Tags Telephone Device Tags Wall Tags Window Tags Wire Tag Zone Tags | IndependentTag.Create(Document, ElementId, Reference, Boolean, TagMode, TagOrientation, XYZ) | TagMode should be TM_ADDBY_CATEGORY and there should be a related tag family loaded when try to create a tag, otherwise exception will be thrown
Material Tags | IndependentTag.Create(Document, ElementId, Reference, Boolean, TagMode, TagOrientation, XYZ) | TagMode should be TM_ADDBY_MATERIAL and there should be a material tag family loaded, otherwise exception will be thrown
Multi-Category Tags | IndependentTag.Create(Document, ElementId, Reference, Boolean, TagMode, TagOrientation, XYZ) | TagMode should be TM_ADDBY_MULTICATEGORY, and there should be a multi-category tag family loaded, otherwise exception will be thrown
Title Blocks | ViewSheet.Create(Document, ElementId) | The titleblock will be added to the newly created sheet.
Families and family symbols are loaded using the Document.LoadFamily() or Document.LoadFamilySymbol() methods. Some families, such as Beams, have more than one endpoint and are inserted in the same way as a single point instance. Once the linear family instances are inserted, their endpoints can be changed using the Element.Location property. For more information, refer to [Code Samples](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_Code_Samples_html.html).
**Parent page:** [Family Instances](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_html.html)

View File

@@ -0,0 +1,76 @@
# FamilySymbol
# FamilySymbol
The FamilySymbol class represents a single Type within a Family.
Each family can contain one or more family symbols. Each FamilyInstance has an associated FamilySymbol which can be accessed from its Symbol property.
### Thermal Properties
Certain types of families (doors, windows, and curtain wall panels) contain thermal properties as shown in the Type Properties window below for a window.
The thermal properties for a FamilySymbol are represented by the FamilyThermalProperties class and are retrieved using the FamilySymbol.GetThermalProperties() method. The FamilyThermalProperties for a FamilySymbol can be set using SetThermalProperties(). The properties of the FamilyThermalProperties class itself are read-only.
The units for the calculated values are shown in the table below.
**Property** | **Unit**
---|---
HeatTransferCoefficient | watts per meter-squared kelvin (W/(m^2*K)
ThermalResistance | meter-squared kelvin per watt ((m^2*K)/Watt)
The AnalyticConstructionTypeId property is the construction gbXML type and returns the value that corresponds to the 'id' property of a constructionType node in Constructions.xml. The static FamilyThermalProperties.Find() method will find the FamilyThermalProperties by the 'id' property of a constructionType node in Constructions.xml.
### FamilyType Parameters
Some parameters for a FamilySymbol may be FamilyType parameters. For these parameters, the Family.GetFamilyTypeParameterValues() method can be used to get all applicable values for the parameter. The values returned are ElementIds of all family types that match the category specified by the definition of the given parameter. The elements are either of class ElementType or NestedFamilyTypeReference. The second variant is for the types that are nested in families and therefore not accessible otherwise. The NestedFamilyTypeReference element stores only basic information about the nested FamilyType, such as the name of the Type, name of the Family, and a Category. These elements are very low-level and thus bypassed by standard element filters, so the main way to get them is via the Family.GetFamilyTypeParameterValues() method.
The following example demonstrates how to get all the family type parameter values for a FamilyType parameter of a FamilySymbol. The value for the parameter is then changed to another value. This change affects all FamilyInstances using the loaded FamilySymbol.
**Code Region: Get nested FamilyTypes**
---
public void GetNestedFamilyTypes(FamilyInstance instance)
{
// find one FamilyType parameter and all values applicable to it
Parameter aTypeParam = null;
ISet<ElementId> values = null;
Family family = instance.Symbol.Family;
foreach (Parameter param in instance.Symbol.Parameters)
{
ForgeTypeId forgeTypeId = param.Definition.GetDataType();
if (Category.IsBuiltInCategory(forgeTypeId))
{
aTypeParam = param;
values = family.GetFamilyTypeParameterValues(param.Id);
break;
}
}
if (aTypeParam == null)
{
TaskDialog.Show("Warning", "The selected family has no FamilyType parameter defined.");
}
else if (values == null)
{
TaskDialog.Show("Error", "A FamilyType parameter does not have any applicable values!?");
}
else
{
ElementId newValue = values.Last<ElementId>();
if (newValue != aTypeParam.AsElementId())
{
using (Transaction trans = new Transaction(instance.Document, "Setting parameter value"))
{
trans.Start();
aTypeParam.Set(newValue);
trans.Commit();
}
}
}
}
**Parent page:** [Family Instances](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_html.html)

View File

@@ -0,0 +1,30 @@
# Family
# Family
The Family class represents an entire Revit family. It contains the FamilySymbols used by FamilyInstances.
### Loading Families
The Document class contains the LoadFamily() and LoadFamilySymbol() methods.
* LoadFamily() loads an entire family and all of its types or symbols into the project.
* LoadFamilySymbol() loads only the specified family symbol from a family file into the project.
Note: To improve the performance of your application and reduce memory usage, if possible load specific FamilySymbols instead of entire Family objects.
* The family file path is retrieved using the Options.Application object GetLibraryPaths() method.
* The Options.Application object is retrieved using the Application object Options property.
* In LoadFamilySymbol(), the input argument Name is the same string value returned by the FamilySymbol object Name property.
For more information, refer to [Code Samples](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_Code_Samples_html.html).
### Categories
The Family.FamilyCategory property indicates the category of the Family such as Columns, Furniture, Structural Framing, or Windows.
**Parent page:** [Family Instances](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_html.html)

View File

@@ -0,0 +1,50 @@
# Identifying Elements
# Identifying Elements
In Revit, the easiest way to judge whether an element is a FamilyInstance or not is by using the properties dialog box.
* If the family name starts with System Family and the Load button is disabled, it belongs to System Family.
**Figure 41: System Family**
* A general FamilyInstance, which belongs to the Component Family, does not start with System Family.
* For example, in the following picture the family name for the desk furniture is Desk. In addition, the Load button is enabled.
* _Figure 42: Component Family*_
* There are some exceptions, for example: Mass and in-place member. The Family and Type fields are blank.
* _Figure 43: Mass or in-place member example*_
Families in the Revit Platform API are represented by three objects:
* Family
* FamilySymbol
* FamilyInstance
Each object plays a significant role in the family structure.
The Family object represents an entire family such as Single-Flush doors. For example, the Single-Flush door Family corresponds to the Single-Flush.rfa file. The Family object contains several FamilySymbols that are used to get all family symbols to facilitate swapping instances from one symbol to another.
The FamilySymbol object represents a specific set of family settings corresponding to a Type in the Revit UI, such as 34"×80".
The FamilyInstance object represents an actual Type (FamilySymbol) instance in the Revit project. For example, in the following picture, the FamilyInstance is a single door in the project.
* Each FamilyInstance has one FamilySymbol. The door is an instance of a 34"×80".
* Each FamilySymbol belongs to one Family. The 34"×80" symbol belongs to a Single-Flush family.
* Each Family contains one or more FamilySymbols. The Single-Flush family contains a 34"×80" symbol, a 34"×84" symbol, a 36"×84" and so on.
Note: While most component elements are exposed through the API classes FamilySymbol and FamilyInstance, some have been wrapped with specific API classes. For example, AnnotationSymbolType wraps FamilySymbol and AnnotationSymbol wraps FamilyInstance.
**Parent page:** [Family Instances](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_html.html)

View File

@@ -0,0 +1,24 @@
# Family Instances
# Family Instances
In this section, you will learn about the following:
* The relationship between family and family instance
* Family and family instance features
* How to load or create family and family instance features
* The relationship between family instance and family symbol
**Pages in this section**
* [Identifying Elements](Family_Instances/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_Identifying_Elements_html.html)
* [Family](Family_Instances/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_Family_html.html)
* [FamilyInstances](Family_Instances/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_FamilyInstances_html.html)
* [Code Samples](Family_Instances/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_Code_Samples_html.html)
* [FamilySymbol](Family_Instances/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Family_Instances_FamilySymbol_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,20 @@
# Collection Classes
# Collection Classes
Specialized geometry collection classes exist in the Revit API.
The API provides the following collection classes based on the items they contain:
**Table 50: Geometry Collection Classes**
**Class/Type** | **Corresponding Collection Classes** | **Corresponding Iterators**
---|---|---
Edge | EdgeArray, EdgeArrayArray | EdgeArrayIterator, EdgeArrayArrayIterator
Face | FaceArray | FaceArrayIterator
Reference | ReferenceArray | ReferenceArrayIterator
Double value | DoubleArray | DoubleArrayIterator
All of these classes use very similar methods and properties to do similar work. For more details, refer to [Collections](../../Basic_Interaction_with_Revit_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Collections_html.html).
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,60 @@
# Example: Retrieve Geometry Data from a Beam
# Example: Retrieve Geometry Data from a Beam
This section illustrates how to get solids and curves from a beam. You can retrieve column and brace geometry data in a similar way. The GeometryElement may contain the desired geometry as a Solid or GeometryInstance depending on whether a beam is joined or standalone, and this code covers both cases.
Note: If you want to get the beam and brace driving curve, call the FamilyInstance Location property where a LocationCurve is available.
The sample code is shown as follows:
**Code Region 20-10: Getting solids and curves from a beam**
---
public void GetCurvesFromABeam(Autodesk.Revit.DB.FamilyInstance beam,
Autodesk.Revit.DB.Options options)
{
Autodesk.Revit.DB.GeometryElement geomElem = beam.get_Geometry(options);
Autodesk.Revit.DB.CurveArray curves = new CurveArray();
System.Collections.Generic.List<Autodesk.Revit.DB.Solid> solids = new System.Collections.Generic.List<Autodesk.Revit.DB.Solid>();
//Find all solids and insert them into solid array
AddCurvesAndSolids(geomElem, ref curves, ref solids);
}
private void AddCurvesAndSolids(Autodesk.Revit.DB.GeometryElement geomElem,
ref Autodesk.Revit.DB.CurveArray curves,
ref System.Collections.Generic.List<Autodesk.Revit.DB.Solid> solids)
{
foreach (Autodesk.Revit.DB.GeometryObject geomObj in geomElem)
{
Autodesk.Revit.DB.Curve curve = geomObj as Autodesk.Revit.DB.Curve;
if (null != curve)
{
curves.Append(curve);
continue;
}
Autodesk.Revit.DB.Solid solid = geomObj as Autodesk.Revit.DB.Solid;
if (null != solid)
{
solids.Add(solid);
continue;
}
//If this GeometryObject is Instance, call AddCurvesAndSolids
Autodesk.Revit.DB.GeometryInstance geomInst = geomObj as Autodesk.Revit.DB.GeometryInstance;
if (null != geomInst)
{
Autodesk.Revit.DB.GeometryElement transformedGeomElem
= geomInst.GetInstanceGeometry(geomInst.Transform);
AddCurvesAndSolids(transformedGeomElem, ref curves, ref solids);
}
}
}
The above example uses the FamilyInstance.Geometry property to access the true geometry of the beam. To obtain the original geometry of a family instance before it is modified by joins, cuts, coping, extensions, or other post-processing, use the FamilyInstance.GetOriginalGeometry() method.
Note: For more information about how to retrieve the Geometry.Options type object, refer to [Geometry Helper Classes.](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html)
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,86 @@
# Example: Retrieve Geometry Data from a Wall
# Example: Retrieve Geometry Data from a Wall
This walkthrough illustrates how to get geometry data from a wall. The following information is covered:
* Getting the wall geometry edges.
* Getting the wall geometry faces.
**Note:** Retrieving the geometry data from Element in this example is limited because Instance is not considered. For example, sweeps included in the wall are not available in the sample code. The goal for this walkthrough is to give you a basic idea of how to retrieve geometry data but not cover all conditions. For more information about retrieving geometry data from Element, refer to [Example: Retrieve Geometry Data from a Beam](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Example_Retrieve_Geometry_Data_from_a_Beam_html.html).
### Create Geometry Options
In order to get the wall's geometry information, you must create a Geometry.Options object which provides detailed customized options. The code is as follows:
**Code Region 20-1: Creating Geometry.Options**
---
public void CreateOptions(Application application)
{
Autodesk.Revit.DB.Options geomOption = application.Create.NewGeometryOptions();
if (null != geomOption)
{
geomOption.ComputeReferences = true;
geomOption.DetailLevel = ViewDetailLevel.Fine;
// Either the DetailLevel or the View can be set, but not both
//geomOption.View = commandData.Application.ActiveUIDocument.Document.ActiveView;
TaskDialog.Show("Revit", "Geometry Option created successfully.");
}
}
Note: For more information, refer to [Geometry Helper Classes.](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html)
### Retrieve Faces and Edges
Wall geometry is a solid made up of faces and edges. Complete the following steps to get the faces and edges:
1. Retrieve a Geometry.Element instance using the Wall class Geometry property. This instance contains all geometry objects in the Object property, such as a solid, a line, and so on.
2. Iterate the Object property to get a geometry solid instance containing all geometry faces and edges in the Faces and Edges properties.
3. Iterate the Faces property to get all geometry faces.
4. Iterate the Edges property to get all geometry edges.
The sample code follows:
**Code Region 20-2: Retrieving faces and edges**
---
private void GetFacesAndEdges(Wall wall)
{
String faceInfo = "";
Autodesk.Revit.DB.Options opt = new Options();
Autodesk.Revit.DB.GeometryElement geomElem = wall.get_Geometry(opt);
foreach (GeometryObject geomObj in geomElem)
{
Solid geomSolid = geomObj as Solid;
if (null != geomSolid)
{
int faces = 0;
double totalArea = 0;
foreach (Face geomFace in geomSolid.Faces)
{
faces++;
faceInfo += "Face " + faces + " area: " + geomFace.Area.ToString() + "\n";
totalArea += geomFace.Area;
}
faceInfo += "Number of faces: " + faces + "\n";
faceInfo += "Total area: " + totalArea.ToString() + "\n";
foreach (Edge geomEdge in geomSolid.Edges)
{
// get wall's geometry edges
}
}
}
TaskDialog.Show("Revit", faceInfo);
}
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,86 @@
# Extrusion Analysis of a Solid
# Extrusion Analysis of a Solid
The utility class ExtrusionAnalyzer allows you to attempt to “fit” a given piece of geometry into the shape of an extruded profile. An instance of this class is a single-time use class which should be supplied a solid geometry, a plane, and a direction. After the ExtrusionAnalyzer has been initialized, you can access the results through the following members:
* The GetExtrusionBase() method returns the calculated base profile of the extruded solid aligned to the input plane.
* The CalculateFaceAlignment() method can be used to identify all faces from the original geometry which do and do not align with the faces of the calculated extrusion. This could be useful to figure out if a wall, for example, has a slanted join at the top as would be the case if there is a join with a roof. If a face is unaligned, something is joined to the geometry that is affecting it.
* To determine the element that produced the non-aligned face, pass the face to Element.GetGeneratingElementIds(). For more details on this utility, see the following section.
The ExtrusionAnalyzer utility works best for geometry which are at least somewhat “extrusion-like”, for example, the geometry of a wall which may or may not be affected by end joins, floor joins, roof joins, openings cut by windows and doors, or other modifications. Rarely for specific shape and directional combinations the analyzer may be unable to determine a coherent face to act as the base of the extrusion an InvalidOperationException will be thrown in these situations.
In this example, the extrusion analyzer is used to calculate and outline a shadow formed from the input solid and the sun direction.
**Code Region: Use Extrusion Analyzer to calculate and draw a shadow outline.**
---
/// <summary>
/// Draw the shadow of the indicated solid with the sun direction specified.
/// </summary>
/// <remarks>The shadow will be outlined with model curves added to the document.
/// A transaction must be open in the document.</remarks>
/// <param name="document">The document.</param>
/// <param name="solid">The target solid.</param>
/// <param name="targetLevel">The target level where to measure and draw the shadow.</param>
/// <param name="sunDirection">The direction from the sun (or light source).</param>
/// <returns>The curves created for the shadow.</returns>
/// <throws cref="Autodesk.Revit.Exceptions.InvalidOperationException">Thrown by ExtrusionAnalyzer when the geometry and
/// direction combined do not permit a successful analysis.</throws>
private static ICollection<ElementId> DrawShadow(Document document, Solid solid, Level targetLevel, XYZ sunDirection)
{
// Create target plane from level.
Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ(0, 0, targetLevel.ProjectElevation));
// Create extrusion analyzer.
ExtrusionAnalyzer analyzer = ExtrusionAnalyzer.Create(solid, plane, sunDirection);
// Get the resulting face at the base of the calculated extrusion.
Face result = analyzer.GetExtrusionBase();
// Convert edges of the face to curves.
CurveArray curves = document.Application.Create.NewCurveArray();
foreach (EdgeArray edgeLoop in result.EdgeLoops)
{
foreach (Edge edge in edgeLoop)
{
curves.Append(edge.AsCurve());
}
}
// Get the model curve factory object.
Autodesk.Revit.Creation.ItemFactoryBase itemFactory;
if (document.IsFamilyDocument)
itemFactory = document.FamilyCreate;
else
itemFactory = document.Create;
// Add a sketch plane for the curves.
CurveLoop loop = new CurveLoop();
foreach (Curve currentCurve in curves)
{
loop.Append(currentCurve);
}
SketchPlane sketchPlane = SketchPlane.Create(document, loop.GetPlane());
document.Regenerate();
// Add the shadow curves
ModelCurveArray curveElements = itemFactory.NewModelCurveArray(curves, sketchPlane);
// Return the ids of the curves created
List<ElementId> curveElementIds = new List<ElementId>();
foreach (ModelCurve curveElement in curveElements)
{
curveElementIds.Add(curveElement.Id);
}
return curveElementIds;
}
The utility above above can be used to compute the shadow of a given mass with respect to the current sun and shadows settings for the view:
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,156 @@
# Finding Geometry by Ray Projection
# Finding Geometry by Ray Projection
The ReferenceIntersector class can be used to find elements that are intersected by a given ray.
## ReferenceIntersector
This class allows an application to use Revit's picking tools to find elements and geometry. This class uses a ray from a point in a specified direction to find the geometry that is hit by the ray.
The class intersects 3D geometry only and requires a 3D view on creation. It is possible to use a 3D view which has been cut by a section box, or which has view-specific geometry and graphics options set. The visibility settings on the input view will determine if a particular element is returned (for example, hidden elements will never be returned by this tool, nor will elements whose geometry is outside the section box of the view).
The ReferenceIntersector class supports filtering the output based on element or reference type. The output can be customized based on which constructor is used or by using methods and properties of the class prior to calling a method to perform the ray projection.
There are 4 constructors.
Name | Description
---|---
`ReferenceIntersector(View3D)` | Constructs a ReferenceIntersector which is set to return intersections from all elements and representing all reference target types.
`ReferenceIntersector(ElementFilter, FindReferenceTarget, View3D)` | Constructs a ReferenceIntersector which is set to return intersections from any element which passes the filter.
`ReferenceIntersector(ElementId, FindReferenceTarget, View3D)` | Constructs a ReferenceIntersector which is set to return intersections from a single target element only.
`ReferenceIntersector(ICollection<ElementId>, FindReferenceTarget, View3D)` | Constructs a ReferenceIntersector which is set to return intersections from any of a set of target elements.
The FindReferenceTarget enumeration includes the options: Element, Mesh, Edge, Curve, Face or All.
### Finding elements
There are two methods to project a ray, both of which take as input the origin of the ray and its direction. Only references for elements that are in front of the ray will be returned. The Find() method returns a collection of ReferenceWithContext objects which match the ReferenceIntersector's criteria. This object contains the intersected reference, which can be both the elements and geometric references which intersect the ray. Some element references returned will have a corresponding geometric object which is also intersected (for example, rays passing through openings in walls will intersect the wall and the opening element). If interested only in true physical intersections an application should discard all references whose Reference is of type Element.
The FindNearest() method behaves similarly to the Find() method, but only returns the intersected reference nearest to the ray origin.
The ReferenceWithContext returned includes a proximity parameter. This is the distance between the origin of the ray and the intersection point. An application can use this distance to exclude items too far from the origin for a particular geometric analysis. An application can also use this distance to take on some interesting problems involving analyzing the in place geometry of the model.
Note: These methods will not return intersections with elements which are not in the active design option.
#### Elements in linked files
The FindReferencesInRevitLinks property offers an option to return element results encountered in Revit Links. If set to false, no Reference to any Element from a Revit Link will be found by the ReferenceIntersector, and all References returned will be to an element in the host document only. If set to true, the results may include both References to Elements in hosts and References to Elements from a link instance.
If a list of target ElementIds is set in the ReferenceIntersector, references will be returned only if the ElementId matches the id of the intersected RevitLinkInstance. If there is a match, any intersecting elements in the link will be returned (their ids will not be compared with the target ids list).
If there is an ElementFilter applied, the elements in the link will be evaluated against the stored ElementFilter. Note that results may not be as expected if the filter applied is geometric (such as a BoundingBox filter or ElementIntersects filter). This is because the filter will be evaluated for linked elements in the coordinates of the linked model, which may not match the coordinates of the elements as they appear in the host model. Also, ElementFilters that accept a Document and/or ElementId as input during their instantiation will not correctly pass elements that appear in the link, because the filter will not be able to match link elements to the filter's criteria.
### Find elements near elements
One major use for this tool is to find elements in close proximity to other elements. This allows an application to use the tool as its "eyes" and determine relationships between elements which don't have a built-in relationship already.
For example, the ray-tracing capability can be used to find columns embedded in walls. As columns and walls don't maintain a relationship directly, this class allows us to find potential candidates by tracing rays just outside the extents of the wall, and looking for intersections with columns.
**Example: Find columns embedded in walls**
### Measure distances
This class could also be used to measure the vertical distance from a skylight to the nearest floor.
**Example: measure with ReferenceIntersector.FindNearest()**
**Code Region: Measuring Distance using Ray Projection**
---
public class RayProjection : IExternalCommand
{
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements)
{
Document doc = revit.Application.ActiveUIDocument.Document;
ICollection<ElementId> selectedIds = revit.Application.ActiveUIDocument.Selection.GetElementIds();
// If skylight is selected, process it.
FamilyInstance skylight = null;
if (selectedIds.Count == 1)
{
foreach (ElementId id in selectedIds)
{
Element e = doc.GetElement(id);
if (e is FamilyInstance)
{
FamilyInstance instance = e as FamilyInstance;
bool isWindow = (instance.Category.Id.Value == (int)BuiltInCategory.OST_Windows);
bool isHostedByRoof = (instance.Host.Category.Id.Value == (int)BuiltInCategory.OST_Roofs);
if (isWindow && isHostedByRoof)
{
skylight = instance;
}
}
}
}
if (skylight == null)
{
message = "Please select one skylight.";
return Result.Cancelled;
}
// Calculate the height
Line line = CalculateLineAboveFloor(doc, skylight);
// Create a model curve to show the distance
Plane plane = Plane.CreateByNormalAndOrigin(new XYZ(1, 0, 0), line.GetEndPoint(0));
SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
ModelCurve curve = doc.Create.NewModelCurve(line, sketchPlane);
// Show a message with the length value
TaskDialog.Show("Distance", "Distance to floor: " + String.Format("{0:f2}", line.Length));
return Result.Succeeded;
}
/// <summary>
/// Determines the line segment that connects the skylight to the nearest floor.
/// </summary>
/// <returns>The line segment.</returns>
private Line CalculateLineAboveFloor(Document doc, FamilyInstance skylight)
{
// Find a 3D view to use for the ReferenceIntersector constructor
FilteredElementCollector collector = new FilteredElementCollector(doc);
Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
View3D view3D = collector.OfClass(typeof(View3D)).Cast<View3D>().First<View3D>(isNotTemplate);
// Use the center of the skylight bounding box as the start point.
BoundingBoxXYZ box = skylight.get_BoundingBox(view3D);
XYZ center = box.Min.Add(box.Max).Multiply(0.5);
// Project in the negative Z direction down to the floor.
XYZ rayDirection = new XYZ(0, 0, -1);
ElementClassFilter filter = new ElementClassFilter(typeof(Floor));
ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D);
ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, rayDirection);
Reference reference = referenceWithContext.GetReference();
XYZ intersection = reference.GlobalPoint;
// Create line segment from the start point and intersection point.
Line result = Line.CreateBound(center, intersection);
return result;
}
}
### Ray bouncing/analysis
The references returned by ReferenceIntersector.Find() include the intersection point on the geometry. Knowing the intersection point on the face, the face's material, and the ray direction allows an application to analyze reflection and refraction within the building. The following image demonstrates the use of the intersection point to reflect rays intersected by model elements; model curves were added to represent the path of each ray.
**Example: Rays bouncing off intersected faces**
### Find intersections/collisions
Another use of the ReferenceIntersector class would be to detect intersections (such as beams or pipes) which intersect/interference with the centerline of a given beam or pipe.
**Example: Reroute elements around interferences**
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,33 @@
# Curve Parameterization
# Curve Parameterization
Curves in the Revit API can be described as mathematical functions of an input parameter “u”, where the location of the curve at any given point in XYZ space is a function of “u”.
Curves can be bound or unbound. Unbound curves have no endpoints, representing either an infinite abstraction (an unbound line) or a cyclic curve (a circle or ellipse).
In Revit, the parameter “u” can be represented in two ways:
* A normalized parameter. The start value of the parameter is 0.0, and the end value is 1.0. For some curve types, this makes evaluation of the curve along its extents very easy, for example, the midpoint of a line is at parameter 0.5. (Note that for more complex curve equations like Splines this assumption cannot always be made).
* A raw parameter. The start and end value of the parameter can be any value. For a given curve, the value of the minimum and maximum raw parameter can be obtained through Curve.GetEndParameter(int) . Raw parameters are useful because their units are the same as the Revit default units (feet). So to obtain a location 5 feet along the curve from the start point, you can take the raw parameter at the start and add 5 to it. Raw parameters are also the only way to evaluate unbound curves.
The methods Curve.ComputeNormalizedParameter() and Curve.ComputeRawParameter() automatically scale between the two parameter types. The method Curve.IsInside() evaluates a raw parameter to see if it lies within the bounds of the curve.
You can use the parameter to evaluate a variety of properties of the curve at any given location:
* The XYZ location of the given curve. This is returned from Curve.Evaluate(). Either the raw or normalized parameter can be supplied. If you are also calling ComputeDerivatives(), this is also the .Origin property of the Transform returned by that method.
* The first derivative/tangent vector of the given curve. This is the .BasisX property of the Transform returned by Curve.ComputeDerivatives().
* The second derivative/normal vector of the given curve. This is the .BasisY property of the Transform returned by Curve.ComputeDerivatives().
* The _binormal_ vector of the given curve, defined as the cross-product of the tangent and normal vector. This is the .BasisZ property of the Transform returned by Curve.ComputeDerivatives().
All of the vectors returned are non-normalized (but you can normalize any vector in the Revit API with XYZ.Normalize()). Note that there will be no value set for the normal and binormal vector when the curve is a straight line. You can calculate a normal vector to the straight line in a given plane using the tangent vector.
The API sample “DirectionCalculation” uses the tangent vector to the wall location curve to find exterior walls that face south:
Finding and highlighting south facing exterior walls
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,32 @@
# Curve Analysis
# Curve Analysis
There are several Curve methods which are tools suitable for use in geometric analysis.
In some cases, these APIs do more than you might expect by a quick review of their names.
### Intersect()
The Intersect method allows you compare two curves to find how they differ or how they are similar. It can be used in the manner you might expect, to obtain the point or point(s) where two curves intersect one another, but it can also be used to identify:
* Collinear lines
* Overlapping lines
* Identical curves
* Totally distinct curves with no intersections
The return value identifies these different results, and the output IntersectionSetResult contains information on the intersection point(s).
### Project()
The Project method projects a point onto the curve and returns information about the nearest point on the curve, its parameter, and the distance from the projection point.
### Tessellate()
This splits the curve into a series of linear segments, accurate within a default tolerance. For Curve.Tessellate(), the tolerance is slightly larger than 1/16”. This tolerance of approximation is the tolerance used internally by Revit as adequate for display purposes.
Note that only lines may be split into output of only two tessellation points; non-linear curves will always output more than two points even if the curve has an extremely large radius which might mathematically equate to a straight line.
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,40 @@
# Curve Collections
# Curve Collections
The Revit API uses different types of collections of curves as inputs.
**Note** : Newer API methods use .NET collections of Curves in place of CurveArray and CurveArrArray.
## CurveLoop
A CurveLoop represents a specific chain of curves joined end-to-end. It can represent a closed loop or an open one. The members of the CurveLoop may be directly iterated, as the class implements `IEnumerable<Curve>`. The iteration provides copies of the curves directly contained in the loop; modification of the curves will not affect the curves that are contained in the loop. CurveLoops can be created using:
* CurveLoop.Create() - creates a new CurveLoop from a list of curves.
* CurveLoop.CreateViaCopy() - creates a new CurveLoop as a copy of an existing CurveLoop.
* CurveLoop.CreateViaThicken(Curve, double, XYZ) - creates a new closed CurveLoop by thickening the input curve with respect to a given plane.
* CurveLoop.CreateViaThicken(CurveLoop, double, XYZ) -creates a new closed curve loop by thickening the input open curve loop with respect to a given plane.
* CurveLoop.CreateViaTransform() - creates a new CurveLoop as a transformed copy of the input CurveLoop. Note that the thickness parameter for the overloaded CreateViaThicken() method must result in a curve which exceed Revit's short curve tolerance (Application.ShortCurveTolerance), otherwise an exception will be thrown.
`CurveLoop.Transform()` performs similarly to CreateViaTransform(), but it transforms the curves contained within the CurveLoop rather than creating a transformed copy.
`CurveLoop.NumberOfCurves` returns the number of curves in the curve loop.
`CurveLoop.CreateViaOffset()` creates a new curve loop that is an offset of the existing curve loop. This can be done in two ways:
* With a single offset distance.
* With an array of offset distances. The size of this array must match the size of the curve loop. The curve at position i will be offset with the double at position i in the array.
### CurveArray
This collection class represents an arbitrary collection of curves. Create it using its constructor.
### CurveArrArray
This collection class is a collection of CurveArrays. When this is used, the organization of the sub-elements of this array have meaning for the method this is passed to; for example, in NewExtrusion() multiple CurveArrays should represent different closed loops.
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,119 @@
# Curve Creation
# Curve Creation
Curves are often needed as inputs to Revit API methods. They can be created a number of ways.
Curves have a number of derived types with static methods for curve creation. The base Curve class also has methods for creating new Curves from existing curves.
Curve creation methods prevent creation of curves that are shorter than Revit's tolerance. This tolerance is exposed through the Application.ShortCurveTolerance property.
### Curve
The Curve class has several methods for creating new curves from existing curves.
* Clone() - creates a copy of this curve.
* CreateOffset() - creates a new curve offset from this one.
* CreateReversed() - creates a new curve with the opposite orientation of the existing curve.
* Curve.CreateTransformed() - creates a new instance of a curve as a transformation of this curve.
### Line
There are two static methods for creating a new Line.
* CreateBound() - creates a new bound linear curve between two points.
* CreateUnbound() - creates a new unbound linear curve given an origin and a direction.
**Code Region: Create an unbound linear curve**
---
// define start point and direction for unbound line
XYZ startPoint = new XYZ(0, 0, 0);
XYZ directionPt = new XYZ(10, 10, 10);
// create line
Line line = Line.CreateUnbound(startPoint, directionPt);
### Arc
The overloaded static Create() method allows for an Arc to be created in one of three ways:
* based on 3 points
**Code Region: Create arc with 3 points**
---
public void ThreePointArc()
{
// Create a new arc using two ends and a point on the curve
XYZ end0 = new XYZ(1, 0, 0); // start point of the arc
XYZ end1 = new XYZ(10, 10, 10); // end point of the arc
XYZ pointOnCurve = new XYZ(10, 0, 0); // point along arc
Arc arc = Arc.Create(end0, end1, pointOnCurve);
}
* based on a plane, radius, and angles
**Code Region: Create arc with plane**
---
public Arc CreateArcByGivingPlane(Autodesk.Revit.ApplicationServices.Application application, Plane plane)
{
// Create an arc which is placed on the plane and whose center is the plane's origin
double radius = 10;
double startAngle = 0; // The unit is radian
double endAngle = 2 * Math.PI; // this arc will be a circle
return Arc.Create(plane, radius, startAngle, endAngle);
}
* based on center, radius, angles and two axes
**Code Region: Create arc with axes**
---
public void CreateArcByCenterRadius()
{
// Create a new arc defined by its center, radius, angles and 2 axes
double radius = 10;
double startAngle = 0; // In radian
double endAngle = Math.PI; // In radian
XYZ center = new XYZ(5, 0, 0);
XYZ xAxis = new XYZ(1, 0, 0); // The x axis to define the arc plane. Must be normalized
XYZ yAxis = new XYZ(0, 1, 0); // The y axis to define the arc plane. Must be normalized
Arc arc = Arc.Create(center, radius, startAngle, endAngle, xAxis, yAxis);
}
Note for the latter two options, if the angle range is equal to or greater than 2 * PI, the curve will be automatically converted to an unbounded circle.
### Ellipse
The static CreateCurve() method creates an Ellipse given the center, the x vector and y vector radii of the ellipse, the x and y axes to define the plane of the ellipse and the start and end parameters. If the x-radius and y-radius are almost equal it will return an arc, otherwise it will return an ellipse.
### Cylindrical Helix
The static Create() method of CylindricalHelix creates a new CylindricalHelix from the base point of the axis, a radius, x vector, z vector, pitch, a start angle to specify the start point of the helix and an end angle to specify the end point of the helix. The z vector is the axis direction and should be perpendicular to the x vector. A positive pitch yields a right-handed helix while a negative pitch yields a left-handed helix.
### NURBS
The NurbSpline class represents a NURBS, or Non-Uniform Rational B-Spline, curve. The overloaded static CreateCurve() method offers multiple ways to create a NURBS curve. The first way is using the same calculations that Revit uses when sketching splines in the user interface. It takes a list of control points and weights to create a new NurbSpline. Knots and degree of the spline are computed from the given control points and weights.
A second option also requires a list of control points and weights, but also a list of knots as well as the degree of the NurbSpline. The degree must be 1 or greater. There must be at least degree+1 control points. The size of knots must equal the sum of degree, the size of the control points array and 1. The first degree+1 knots should be identical, as should the last degree+1 knots. The knots in the middle of the sequence must be non-decreasing.
A third option only requires control points and weights. There must be at least 2 control points and the number of weights must be equal to the number of control points. The values of all weights must be positive.
In all cases, the created curve may be a NURBSpline or a simpler curve such as line or arc. This is consistent with Revit expectations that the simplest possible representation of curve should be used in Revit elements.
### Hermite Spline
The overloaded static HermiteSpline.Create() method provides two options for creating Hermite splines. The simplest way creates a Hermite spline with default tangency at its endpoints and requires only a list of control points and a flag indicating whether or not the Hermite spline is periodic. The second option creates a Hermite spline with specified tangency at its endpoints. It has an additional parameter of a HermiteSplineTangents object to specify the tangents at the start and/or end of the curve.
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,24 @@
# Curve Types
# Curve Types
Revit uses a variety of curve types to represent curve geometry in a document.
Curve types in Revit include:
**Curve type** | **Revit API class** | **Definition** | **Notes**
---|---|---|---
Bound line | Line | A line segment defined by its endpoints. | Obtain endpoints from Curve.GetEndpoint()
Unbound line | Line | An infinite line defined by a location and direction | Identify these with Curve.IsBound. Evaluate point and tangent vector at raw parameter= 0 to find the input parameters for the equation of the line.
Arc | Arc | A bound circular arc | Begin and end at a certain angle. These angles can be obtained by the raw parameter values at each end of the arc.
Circle | Arc | An unbound circle | Identify with Curve.IsBound. Use raw parameter for evaluation (from 0 to 2π)
Cylindrical helix | CylindricalHelix | A helix wound around a cylinder making constant angle with the axis of the cylinder | Used only in specific applications in stairs and railings, and should not be used or encountered when accessing curves of other Revit elements and geometry.
Elliptical arc | Ellipse | A bound elliptical segment |
Ellipse | Ellipse | An unbound ellipse | Identify with Curve.IsBound. Use raw parameter for evaluation (from 0 to 2π)
NURBS | NurbSpline | A non-uniform rational B-spline | Used for splines sketched in various Revit tools, plus imported geometry
Hermite | HermiteSpline | A spline interpolate between a set of points | Used for tools like Curve by Points and flexible ducts/pipes, plus imported geometry
CurveUV| A curve in the 2D parameter space of a surface in 3D space. | This class helps translate geometry (BReps) from external applications to Revit. Some geometric modelers represent the shape of an edge in a solid (or open shell) by a 3D curve, others use 2D curves in the parameter spaces of the edges faces, and others might use both. Revit can benefit from being given the CurveUVs for an edge when translating geometry, and this class accommodates the passing of such information.
Mathematical representations of all of the Revit curve types can be found in: [Mathematical Representation of Face Types](../Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Mathematical_representation_of_face_types_html.html).
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,144 @@
# Mathematical Representations of Curve Types
# Mathematical Representations of Curve Types
This section describes the curve types encountered in Revit geometry, their properties, and their mathematical representations.
### Bound lines
Bound lines are defined by their endpoints. In the Revit API, obtain the endpoints of the line from the Curve-level GetEndPoint() method.
The equation for a point on a bound line in terms of the normalized parameter “u” and the line endpoints is
### Unbound lines
Unbound lines are handled specially in the Revit API. Most curve properties cannot be used, however, Evaluate() and ComputeDerivatives() can be used to obtain locations along the curve when a raw parameter is provided.
The equation for a point for an unbound line in terms of the raw parameter “u” and the line origin and normalized direction vector is
### Arcs and Circles
Arcs and Circles are represented in the Revit API by the Arc class. They are defined in terms of their radius, center and vector normal to the plane of the arc, which are accessible in the Revit API directly from the Arc class as properties.
Circles have the IsBound property set to true. This means they can only be evaluated by using a raw parameter (range from 0 to 2π), and the equation for a point on the circle in terms of the raw parameter is
where the assumption is made that the circle lies in the XY plane.
Arcs begin and end at a certain angle. These angles can be obtained by the raw parameter values at each end of the arc, and angular values between these values can be plugged into the same equation as above.
### Cylindrical Helixes
Cylindrical helixes are represented in the Revit API by the CylindricalHelix class. They are defined in terms of the base point of the axis of the cylinder around which the helix is wound, radius, x and y vectors, pitch, and start and end angles.
### Ellipse and elliptical arcs
Ellipses and elliptical arcs segments are represented in the Revit API by the Ellipse class. Similar to arcs and circles, they are defined in a given plane in terms of their X and Y radii, center, and vector normal to the plane of the ellipse.
Full ellipses have the IsBound property set to true. Similar to circles, they can be evaluated via raw parameter between 0 and 2π:
### NurbsSurfaceData
The following element-wise accessors to NurbsSurfaceData avoid deep-copying large arrays of values when only one element from the array is needed:
* NurbsSurfaceData.GetNumberOfKnotsU()
* NurbsSurfaceData.GetKnotU()
* NurbsSurfaceData.GetNumberOfKnotsV()
* NurbsSurfaceData.GetKnotU()
* NurbsSurfaceData.GetNumberControlPoints()
* NurbsSurfaceData.GetControlPoint()
* NurbsSurfaceData.GetNumberOfWeights()
* NurbsSurfaceData.GetWeight()
### NurbSpline
NURBS (nonuniform rational B-splines) are used for spline segments sketched by the user as curves or portions of 3D object sketches. They are also used to represent some types of imported geometry data.
The data for the NurbSpline include:
* The control points array, of length n+1
* The weights array, also of length n+1
* The curve degree, whose value is equal to one less than the curve order (k)
* The knot vector, of length n + k +1
NurbSplines as used in Revits sketching tools can be generated from the control points and degree alone using an algorithm. The calculations performed by Revits algorithm can be duplicated externally, see this sample below:
public void Nurb(ModelCurve curve)
{
NurbSpline spline = curve.GeometryCurve as NurbSpline;
DoubleArray knots = spline.Knots;
// Convert to generic collection
List<double> knotList = new List<double>();
for(int i = 0; i < knots.Size; i++)
{
knotList.Add(knots.get_Item(i));
}
// Preparation - get distance between each control point
IList<XYZ> controlPoints = spline.CtrlPoints;
int numControlPoints = controlPoints.Count;
double[] chordLengths = new double[numControlPoints - 1];
for(int iControlPoint = 1; iControlPoint < numControlPoints; ++iControlPoint)
{
double chordLength =
controlPoints[iControlPoint].DistanceTo(controlPoints[iControlPoint - 1]);
chordLengths[iControlPoint - 1] = chordLength;
}
int degree = spline.Degree;
int order = degree + 1;
int numKnots = numControlPoints + order;
double[] computedKnots = new double[numKnots];
int iKnot = 0;
// Start knot with multiplicity degree + 1.
double startKnot = 0.0;
double knot = startKnot;
for(iKnot = 0; iKnot < order; ++iKnot)
{
computedKnots[iKnot] = knot;
}
// Interior knots based on chord lengths
double prevKnot = knot;
for(/*blank*/; iKnot <= numControlPoints; ++iKnot)
// Last loop computes end knot but does not set interior knot.
{
double knotIncrement = 0.0;
for (int jj = iKnot - order; jj < iKnot - 1; ++jj)
{
knotIncrement += chordLengths[jj];
}
knotIncrement /= degree;
knot = prevKnot + knotIncrement;
if (iKnot < numControlPoints)
computedKnots[iKnot] = knot;
else
break; // Leave "knot" set to the end knot; do not increment "ii".
prevKnot = knot;
}
// End knot with multiplicity degree + 1.
for(/*blank*/; iKnot < numKnots; ++iKnot)
{
computedKnots[iKnot] = knot;
}
}
#### HermiteSpline
Hermite splines are used for curves which are interpolated between a set of control points, like Curve by Points and flexible ducts and pipes in MEP. They are also used to represent some types of imported geometry data. In the Revit API, the HermiteSpline class offers access to the arrays of points, tangent vectors and parameters through the ControlPoints, Tangents, and Parameters properties.
The equation for the curve between two nodes in a Hermite spline is
where Pk and Pk+1 represent the points at each node, Mk and Mk+1 the tangent vectors, and uk and uk+1 the parameters at the nodes, and the basis functions are:
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,21 @@
# Working with Curves
# Working with Curves
The Curve class provides useful methods for working with curves.
In addition to [methods that are useful for analysis](Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_analysis_html.html "There are several Curve methods which are tools suitable for use in geometric analysis."), the Curve class provides properties and methods to modify a curve or get basic information about it.
## Changing bounds
The MakeBound() method can be used to change the bounds of a curve or to create bounds for a previously unbound curve. MakeUnbound() will make the curve unbound. For both methods, if the curve is marked as read-only (because it was extracted directly from a Revit element or collection/aggregation object), calling this method causes the object to be changed to carry a disconnected copy of the original curve. The modification will not affect the original curve or the object that supplied it.
## Graphics style
Curve inherits the GraphicsStyleId read-only property from GeometryObject, which provides the ElementId of the GraphicsStyle assigned to the Curve. The method Curve.SetGraphicsStyleId() can be used to set the GraphicsStyle Id of the Curve. Many methods in the Revit API will not use the graphics style associated to this curve. For example, curves used as portions of the sketch of an element will not read this property. Newly created curve elements will not use this value either, as they inherit their graphical properties from their associated category.
## Curve length
Curve has two properties associated with length. The Length property will return the exact length of the curve. It computes the length of the curve using analytical or numeric integration. There is no performance hit for lines and arcs. For a faster approximation, the ApproximateLength property quickly estimates the length of the curve, but it may deviate by a factor of 2 in some cases. This computation is exact for lines and arcs.
**Parent page:** [Curves](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)

View File

@@ -0,0 +1,19 @@
# Curves
# Curves
A curve represents a path in 2 or 3 dimensions in the Revit model. Curves may represent the entire extent of an elements geometry (e.g., CurveElements) or may appear as a single piece of the geometry of an element (e.g., the centerline of a wall or duct). Curves and collections of curves are used as inputs in many element creation methods in the API.
**Pages in this section**
* [Curve Analysis](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_analysis_html.html)
* [Working with Curves](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Working_with_Curves_html.html)
* [Curve Collections](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_collections_html.html)
* [Curve Creation](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_creation_html.html)
* [Curve Parameterization](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_Parameterization_html.html)
* [Curve Types](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Curve_types_html.html)
* [Mathematical Representations of Curve Types](Curves/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_Mathematical_representations_of_curve_types_html.html)
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,113 @@
# GeometryInstances
# GeometryInstances
A GeometryInstance represents a set of geometry stored by Revit in a default configuration, and then transformed into the proper location as a result of the properties of the element. The most common situation where GeometryInstances are encountered is in Family instances. Revit uses GeometryInstances to allow it to store a single copy of the geometry for a given family and reuse it in multiple instances.
Note that not all Family instances will include GeometryInstances. When Revit needs to make a unique copy of the family geometry for a given instance (because of the effect of local joins, intersections, and other factors related to the instance placement) no GeometryInstance will be encountered; instead the Solid geometry will be found at the top level of the hierarchy.
A GeometryInstance offers the ability to read its geometry through the GetSymbolGeometry() and GetInstanceGeometry() methods. These methods return another Autodesk.Revit.DB.GeometryElement which can be parsed just like the first level return.
GetSymbolGeometry() returns the geometry represented in the coordinate system of the family. Use this, for example, when you want a picture of the “generic” table without regards to the orientation and placement location within the project. This is also the only overload which returns the actual Revit geometry objects to you, and not copies. This is important because operations which use this geometry as input to creating other elements (for example, dimensioning or placement of face-based families) require the reference to the original geometry.
GetInstanceGeometry() returns the geometry represented in the coordinate system of the project where the instance is placed. Use this, for example, when you want a picture of the specific geometry of the instance in the project (for example, ensuring that tables are placed parallel to the walls of the room). This always returns a copy of the element geometry, so while it would be suitable for implementation of an exporter or a geometric analysis tool, it would not be appropriate to use this for the creation of other Revit elements referencing this geometry.
There are also overloads for both GetInstanceGeometry() and GetSymbolGeometry() that transform the geometry by any arbitrary coordinate system. These methods always return copies similar to GetInstanceGeometry().
The GeometryInstance also stored a transformation from the symbol coordinate space to the instance coordinates. This transform is accessible as the Transform property. It is also the transformation used when extracting a the copy of the geometry via GetInstanceGeometry(). For more details, refer to [Geometry Helper Classes](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html).
**2 family instances placed with different transforms - the same geometry will be acquired from both**
Instances may be nested several levels deep for some families. If you encounter nested instances they may be parsed in a similar manner as the first level instance.
Two samples are presented to explain how geometry of instances can be parsed.
In this sample, curves are extracted from the GeometryInstance method GetInstanceGeometry().
**Code Region: Getting curves from an instance**
---
public void GetAndTransformCurve(Autodesk.Revit.ApplicationServices.Application app,
Autodesk.Revit.DB.Element element, Options geoOptions)
{
// Get geometry element of the selected element
Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(geoOptions);
// Get geometry object
foreach (GeometryObject geoObject in geoElement)
{
// Get the geometry instance which contains the geometry information
Autodesk.Revit.DB.GeometryInstance instance =
geoObject as Autodesk.Revit.DB.GeometryInstance;
if (null != instance)
{
GeometryElement instanceGeometryElement = instance.GetInstanceGeometry();
foreach (GeometryObject o in instanceGeometryElement)
{
// Try to find curves
Curve curve = o as Curve;
if (curve != null)
{
// The curve is already transformed into the project coordinate system
}
}
}
}
}
In this sample, the solids are obtained from an instance using GetSymbolGeometry(). The constituent points are then transformed into the project coordinate system using the GeometryInstance.Transform.
**Code Region: Getting solid information from an instance**
---
private void GetAndTransformSolidInfo(Application application, Element element, Options geoOptions)
{
// Get geometry element of the selected element
Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(geoOptions);
// Get geometry object
foreach (GeometryObject geoObject in geoElement)
{
// Get the geometry instance which contains the geometry information
Autodesk.Revit.DB.GeometryInstance instance =
geoObject as Autodesk.Revit.DB.GeometryInstance;
if (null != instance)
{
GeometryElement instanceGeometryElement = instance.GetSymbolGeometry();
foreach (GeometryObject instObj in instanceGeometryElement)
{
Solid solid = instObj as Solid;
if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
{
continue;
}
Transform instTransform = instance.Transform;
// Get the faces and edges from solid, and transform the formed points
foreach (Face face in solid.Faces)
{
Mesh mesh = face.Triangulate();
foreach (XYZ ii in mesh.Vertices)
{
XYZ point = ii;
XYZ transformedPoint = instTransform.OfPoint(point);
}
}
foreach (Edge edge in solid.Edges)
{
foreach (XYZ ii in edge.Tessellate())
{
XYZ point = ii;
XYZ transformedPoint = instTransform.OfPoint(point);
}
}
}
}
}
}
Note: For more details about the retrieved geometry of family instances, refer to [Example: Retrieve Geometry Data from a Beam](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Example_Retrieve_Geometry_Data_from_a_Beam_html.html).
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,30 @@
# Meshes
# Meshes
A mesh is a collection of triangular boundaries which collectively forms a 3D shape. Meshes are typically encountered inside Revit element geometry if those elements were created from certain import operations and also are used in some native Revit elements such as TopographySolid. You can also obtain Meshes as the result of calls to Face.Triangulate() for any given Revit face. The property `Mesh.IsClosed` checks if each edge in the mesh belongs to at least two faces.
**A mesh representing a torus**
The following code sample illustrates how to get the geometry of a Revit face as a Mesh:
**Code region: Extracting the geometry of a mesh**
---
private void GetTrianglesFromFace(Face face)
{
// Get mesh
Mesh mesh = face.Triangulate();
for (int i = 0; i < mesh.NumTriangles; i++)
{
MeshTriangle triangle = mesh.get_Triangle(i);
XYZ vertex1 = triangle.get_Vertex(0);
XYZ vertex2 = triangle.get_Vertex(1);
XYZ vertex3 = triangle.get_Vertex(2);
}
}
Note: The approximation tolerance used for Revit display purposes is used by the parameterless overload of the Triangulate() method (used above) when constructing the Mesh. The overload of Triangulate() that takes a double allows a level of detail to be set between 0 (coarser) and 1 (finer).
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,18 @@
# Points
# Points
A point represents a visible coordinate in 3D space.
Points are typically encountered in mass family elements like ReferencePoint. The Point class provides read access to its coordinates, and an ability to obtain a reference to the point for use as input to other functions.
### Point creation
There are two ways to create Points:
* Create(XYZ) - creates a Point at the given coordinates.
* Create(XYZ, ElementId) - creates a Point at given coordinates and assigns it a color based on the GraphicsStyle element (specified by ElementId).
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,14 @@
# PolyLines
# PolyLines
A polyline is a collection of line segments defined by a set of coordinate points. These are typically encountered in imported geometry. The PolyLine class offers the ability to read the coordinates:
* PolyLine.NumberOfCoordinates the number of points in the polyline
* PolyLine.GetCoordinate() gets a coordinate by index
* PolyLine.GetCoordinates() gets a collection of all coordinates in the polyline
* PolyLine.Evaluate() given a normalized parameter (from 0 to 1) evaluates an XYZ point along the extents of the entire polyline
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,25 @@
# Edge and Face Parameterization
# Edge and Face Parameterization
Edges are boundary curves for a given face.
Iterate the edges of a Face using the EdgeLoops property. Each loop represents one closed boundary on the face. Edges are always parameterized from 0 to 1. It is possible to extract the Curve representation of an Edge with the Edge.AsCurve() and Edge.AsCurveFollowingFace() functions.
An edge is usually defined by computing intersection of two faces. But Revit doesnt recompute this intersection when it draws graphics. So the edge stores a list of points - end points for a straight edge and a tessellated list for a curved edge. The points are parametric coordinates on the two faces. These points are available through the TessellateOnFace() method.
Sections produce “cut edges”. These are artificial edges - not representing a part of the model-level geometry, and thus do not provide a Reference.
### Edge direction
Direction is normally clockwise on the first face (first representing an arbitrary face which Revit has identified for a particular edge). But because two different faces meet at one particular edge, and the edge has the same parametric direction regardless of which face you are concerned with, sometimes you need to figure out the direction of the edge on a particular face.
The figure below illustrated how this works. For Face 0, the edges are all parameterized clockwise. For Face 1, the edge shared with Face 0 is not re-parameterized; thus with respect to Face 1 the edge has a reversed direction, and some edges intersect where both edges parameters are 0 (or 1).
**Edge parameterization**
The API sample “PanelEdgeLengthAngle” shows how to recognize edges that are reversed for a given face. It uses the tangent vector at the edge endpoints to calculate the angle between adjacent edges, and detect whether or not to flip the tangent vector at each intersection to calculate the proper angle.
**PanelEdgeLengthAngle results**
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,7 @@
# Edges
# Edges
The `Edge` class represents the edge of a 3d solid. Edges are defined by intersections of surfaces that form faces of the solid. They have arbitrary parameterization that is normalized from 0 to 1. The `EdgeEndPoint` class represents the start or the end point of an Edge and `SolidUtils.FindAllEdgeEndPointsAtVertex()` finds all EdgeEndPoints at a vertex identified by the input EdgeEndPoint.
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,37 @@
# Face Splitting
# Face Splitting
A face may be split into regions by the Split Face command. The Face.HasRegions property will report if the face contains regions created with the Split Face command, while the Face.GetRegions() method will return a list of faces, one for the main face of the object hosting the Split Face (such as wall of floor) and one face for each Split Face region.
The FaceSplitter class represents an element that splits a face. The FaceSplitter.SplitElementId property provides the id of the element whose face is split by this element. The FaceSplitter class can be used to filter and find these faces by type as shown below.
**Code Region: Find face splitting elements**
---
public void FindSplitting(Application app, Document doc)
{
Autodesk.Revit.DB.Options opt = app.Create.NewGeometryOptions();
opt.ComputeReferences = true;
opt.IncludeNonVisibleObjects = true;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<FaceSplitter> splitElements = collector.OfClass(typeof(FaceSplitter)).Cast<FaceSplitter>().ToList();
foreach(FaceSplitter faceSplitter in splitElements)
{
Element splitElement = doc.GetElement(faceSplitter.SplitElementId);
Autodesk.Revit.DB.GeometryElement geomElem = faceSplitter.get_Geometry(opt);
foreach (GeometryObject geomObj in geomElem)
{
Line line = geomObj as Line;
if (line != null)
{
XYZ end1 = line.GetEndPoint(0);
XYZ end2 = line.GetEndPoint(1);
double length = line.ApproximateLength;
}
}
}
}
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,27 @@
# Face Analysis
# Face Analysis
There are several Face methods which are tools suitable for use in geometric analysis.
## Intersect()
The Intersect method computes the intersection between the face and a curve. It can be used in to identify:
* The intersection point(s) between the two objects.
* The edge nearest the intersection point, if there is an edge close to this location.
* Curves totally coincident with a face.
* Curves and faces which do not intersect.
## Project()
The Project method projects a point on the input face, and returns information on the projection point, the distance to the face, and the nearest edge to the projection point.
## Triangulate()
The Triangulate method obtains a triangular mesh approximating the face. There are two overloads to this method. The parameterless method is similar to Curve.Tessellate() in that the meshs points are accurate within the input tolerance used by Revit (slightly larger than 1/16”). The second Triangulate method accepts a level of detail as an argument ranging from 0 (coarse) to 1 (fine).
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,18 @@
# Face Types
# Face Types
Revit uses a variety of curve types to represent face geometry in a document. These include:
**Face type** | **Revit API class** | **Definition** | **Notes**
---|---|---|---
Plane | PlanarFace | A plane defined by the origin and unit vectors in U and V. |
Cylinder | CylindricalFace | A face defined by extruding a circle along an axis. | .Radius provides the “radius vectors” the unit vectors of the circle multiplied by the radius value.
Cone | ConicalFace | A face defined by rotation of a line about an axis. | .Radius provides the “radius vectors” the unit vectors of the circle multiplied by the radius value.
Revolved face | RevolvedFace | A face defined by rotation of an arbitrary curve about an axis. | .Radius provides the unit vectors of the plane of rotation, there is no “radius” involved.
Ruled surface | RuledFace | A face defined by sweeping a line between two profile curves, or one profile curve and one point. | Both curve(s) and point(s) can be obtained as properties.
Hermite face | HermiteFace | A face defined by Hermite interpolation between points. |
Mathematical representations of all of the Revit face types can be found in: [Mathematical representation of face types](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Mathematical_representation_of_face_types_html.html).
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,26 @@
# Faces
# Faces
Faces in the Revit API can be described as mathematical functions of two input parameters “u” and “v”, where the location of the face at any given point in XYZ space is a function of the parameters.
The U and V directions are automatically determined based on the shape of the given face. Lines of constant U or V can be represented as gridlines on the face, as shown in the example below:
**U and V gridlines on a cylindrical face**
You can use the UV parameters to evaluate a variety of properties of the face at any given location:
* Whether the parameter is within the boundaries of the face, using Face.IsInside().
* The XYZ location of the given face at the specified UV parameter value. This is returned from Face.Evaluate(). If you are also calling ComputeDerivatives(), this is also the .Origin property of the Transform returned by that method.
* The tangent vector of the given face in the U direction. This is the .BasisX property of the Transform returned by Face.ComputeDerivatives().
* The tangent vector of the given face in the V direction. This is the .BasisY property of the Transform returned by Face.ComputeDerivatives().
* The normal vector of the given face. This is the .BasisZ property of the Transform returned by Face.ComputeDerivatives().
* The second derivative with respect to U. This is the .UUDerivative property of the FaceSecondDerivatives returned by Face.ComputeSecondDerivatives().
* The second derivative with respect to V. This is the .VVDerivative of the FaceSecondDerivatives returned by Face.ComputeSecondDerivatives().
* The mixed derivative of the given face. This is the .MixedDerivative of the FaceSecondDerivatives returned by Face.ComputeSecondDerivatives().
All of the vectors returned are non-normalized.
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,76 @@
# Mathematical Representation of Face Types
# Mathematical Representation of Face Types
This section describes the face types encountered in Revit geometry, their properties, and their mathematical representations.
### PlanarFace
A plane defined by origin and unit vectors in U and V. Its parametric equation is:
### CylindricalFace
A face defined by extruding a circle along an axis. The Revit API provides the following properties:
* The origin of the face.
* The axis of extrusion.
* The “radius vectors” in X and Y. These vectors are the circles unit vectors multiplied by the radius of the circle. Note that the unit vectors may represent either a right handed or left handed control frame.
The parametric equation for this face is:
### ConicalFace
A face defined by rotation of a line about an axis. The Revit API provides the following properties:
* The origin of the face.
* The axis of the cone.
* The “radius vectors” in X and Y. These vectors are the unit vectors multiplied by the radius of the circle formed by the revolution. Note that the unit vectors may represent either a right handed or left handed control frame.
* The half angle of the face.
The parametric equation for this face is:
### RevolvedFace
A face defined by rotation of an arbitrary curve about an axis. The Revit API provides the following properties:
* The origin of the face
* The axis of the face
* The profile curve
* The unit vectors for the rotated curve (incorrectly called “Radius”)
The parametric equation for this face is:
### RuledFace
A ruled surface is created by sweeping a line between two profile curves or between a curve and a point. The Revit API provides the curve(s) and point(s) as properties.
The parametric equation for this surface is:
if both curves are valid. If one of the curves is replaced with a point, the equations simplify to one of:
A ruled face with no curves and two points is degenerate and will not be returned.
### HermiteFace
A cubic Hermite spline face. The Revit API provides:
* Arrays of the u and v parameters for the spline interpolation points
* An array of the 3D points at each node (the array is organized in increasing u, then increasing v)
* An array of the tangent vectors at each node
* An array of the twist vectors at each node
The parametric representation of this surface, between nodes (u1, v1) and (u2, v2) is:
Where , , **M H** is the Hermite matrix:
And B is coefficient matrix obtained from the face properties at the interpolation points:
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,90 @@
# Solid Analysis
# Solid Analysis
## Intersection between solid and curve
The method Solid.IntersectWithCurve() calculates the intersection between a closed volume solid and a curve. The SolidCurveIntersectionOptions class can specify whether the results from the IntersectWithCurve() method will include curve segments inside the solid volume or outside. The curve segments inside the solid will include curve segments coincident with the face(s) of the solid. Both the curve segments and the parameters of the segments are available in the results.
The following example uses the IntersectWithCurve() method to calculate the length of rebar that lies within a column.
**Code Region: Finding intersection between solid and curve**
---
private void FindColumnRebarIntersections(Document document, FamilyInstance column)
{
// We will be computing the total length of the rebar inside the column
double totalRebarLengthInColumn = 0;
// Find rebar hosted by this column
RebarHostData rebarHostData = RebarHostData.GetRebarHostData(column);
if (rebarHostData == null)
{
return;
}
IList<Rebar> rebars = rebarHostData.GetRebarsInHost();
if (rebars.Count == 0)
{
return;
}
// Retrieve geometry of the column
Options geomOptions = new Options();
geomOptions.ComputeReferences = true;
geomOptions.DetailLevel = ViewDetailLevel.Fine;
GeometryElement elemGeometry = column.get_Geometry(geomOptions);
// Examine all geometry primitives of the column
foreach (GeometryObject elemPrimitive in elemGeometry)
{
// Skip objects that are not geometry instances
GeometryInstance gInstance = elemPrimitive as GeometryInstance;
if (gInstance == null)
{
continue;
}
// Retrieve geometry of each found geometry instance
GeometryElement instGeometry = gInstance.GetInstanceGeometry();
foreach (GeometryObject instPrimitive in instGeometry)
{
// Skip non-solid sobject
Solid solid = instPrimitive as Solid;
if (solid == null)
{
continue;
}
SolidCurveIntersectionOptions intersectOptions = new SolidCurveIntersectionOptions();
foreach (Rebar rebar in rebars)
{
// Get the centerlines for the rebar to find their intersection with the column
bool selfIntersection = false;
bool suppresHooks = false;
bool suppresBends = false;
IList<Curve> curves = rebar.GetCenterlineCurves(selfIntersection, suppresHooks, suppresBends, MultiplanarOption.IncludeOnlyPlanarCurves, 0);
// Examine every segment of every curve of the centerline
foreach (Curve curve in curves)
{
SolidCurveIntersection intersection = solid.IntersectWithCurve(curve, intersectOptions);
for (int segment = 0; segment <= intersection.SegmentCount - 1; segment++)
{
// Calculate length of the rebar that is inside the column
Curve curveInside = intersection.GetCurveSegment(segment);
double rebarLengthInColumn = curveInside.Length;
totalRebarLengthInColumn = totalRebarLengthInColumn + rebarLengthInColumn;
}
}
}
}
}
}
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,80 @@
# Solid and Face Creation
# Solid and Face Creation
Solids and faces are sometimes used as inputs to other utilities. The Revit API provides several routines which can be used to create such geometry from scratch or to derive it from other inputs.
## Transformed geometry
The method GeometryElement.GetTransformed() returns a copy of the input geometry element with a transformation applied. Because this geometry is a copy, its members cannot be used as input references to other Revit elements, but it can be used geometric analysis and extraction.
## Geometry creation utilities
The GeometryCreationUtilities class is a utility class that allows construction of basic solid shapes:
* Extrusion
* Loft
* Revolution
* Sweep
* Blend
* SweptBlend
The resulting geometry is not added to the document as a part of any element. However, the created Solid can be used as inputs to other API functions, including:
* As the input face(s) to the methods in the Analysis Visualization framework (SpatialFieldManager.AddSpatialFieldPrimitive()) this allows the user to visualize the created shape relative to other elements in the document
* As the input solid to finding 3D elements by intersection
* As one or more of the inputs to a Boolean operation
* As a part of a geometric calculation (using, for example, Face.Project(), Face.Intersect(), or other Face, Solid, and Edge geometry methods)
The following example uses the GeometryCreationUtilities class to create cylindrical shapes based on a location and height. This might be used, for example, to create volumes around the ends of a wall in order to find other walls within close proximity to the wall end points:
**Code Region: Create cylindrical solid**
---
public void MakeCyl(Wall wall, XYZ endPoint, double height, double elevation)
{
// Build cylinder centered at wall end point, extending 3' in diameter
CurveLoop cylinderLoop = new CurveLoop();
XYZ arcCenter = new XYZ(endPoint.X, endPoint.Y, elevation);
Application application = wall.Document.Application;
Arc firstArc = Arc.Create(arcCenter, 1.5, 0, Math.PI, XYZ.BasisX, XYZ.BasisY);
Arc secondArc = Arc.Create(arcCenter, 1.5, Math.PI, 2 * Math.PI, XYZ.BasisX, XYZ.BasisY);
cylinderLoop.Append(firstArc);
cylinderLoop.Append(secondArc);
List<CurveLoop> singleLoop = new List<CurveLoop>();
singleLoop.Add(cylinderLoop);
Solid proximityCylinder = GeometryCreationUtilities.CreateExtrusionGeometry(singleLoop, XYZ.BasisZ, height);
}
## Boolean operations
The BooleanOperationsUtils class provides methods for combining a pair of solid geometry objects.
The ExecuteBooleanOperation() method takes a copy of the input solids and produces a new solid as a result. Its first argument can be any solid, either obtained directly from a Revit element or created via another operation like GeometryCreationUtils.
The method ExecuteBooleanOperationModifyingOriginalSolid() performs the boolean operation directly on the first input solid. The first input must be a solid which is not obtained directly from a Revit element. The property GeometryObject.IsElementGeometry can identify whether the solid is appropriate as input for this method.
Options to both methods include the operations type: Union, Difference, or Intersect. The following example demonstrates how to get the intersection of two solids and then find the volume.
**Code Region: Volume of Solid Intersection**
---
private void ComputeIntersectionVolume(Solid solidA, Solid solidB)
{
Solid intersection = BooleanOperationsUtils.ExecuteBooleanOperation(solidA, solidB, BooleanOperationsType.Intersect);
double volumeOfIntersection = intersection.Volume;
}
The methods CutWithHalfSpace() and CutWithHalfSpaceModifyingOriginalSolid() produce a solid which is the intersection of the input Solid with the half-space on the positive side of the given Plane. The positive side of the plane is the side to which Plane.Normal points. The first method creates a new Solid with the results, while the second modifies the existing solid (which must be a solid created by the application instead of one obtained from a Revit element).
**Parent page:** [Solids, Faces and Edges](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)

View File

@@ -0,0 +1,23 @@
# Solids, Faces and Edges
# Solids, Faces and Edges
A Solid is a Revit API object which represents a collection of faces and edges. Typically in Revit these collections are fully enclosed volumes, but a shell or partially bounded volume can also be encountered. Note that sometimes the Revit geometry will contain unused solids containing zero edges and faces. Check the Edges and Faces members to filter out these solids.
The Revit API offers the ability to read the collections of faces and edges, and also to compute the surface area, volume, and centroid of the solid.
**Pages in this section**
* [Edges](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Edges_html.html)
* [Edge and Face Parameterization](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Edge_and_face_parameterization_html.html)
* [Faces](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Faces_html.html)
* [Face Analysis](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Face_analysis_html.html)
* [Face Splitting](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Face_Splitting_html.html)
* [Face Types](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Face_types_html.html)
* [Mathematical Representation of Face Types](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Mathematical_representation_of_face_types_html.html)
* [Solid Analysis](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Solid_analysis_html.html)
* [Solid and Face Creation](Solids_Faces_and_Edges/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_Solid_and_face_creation_html.html)
**Parent page:** [GeometryObject Class](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)

View File

@@ -0,0 +1,35 @@
# GeometryObject Class
# GeometryObject Class
The indexed property Element.Geometry[] can be used to pull the geometry of any model element (3D element). This applies both to system family instances such as walls, floors and roofs, and also to family instances of many categories, e.g., doors, windows, furniture, or masses.
The property GeometryObject.Id returns an integer value which may be used to identify the GeometryObject in its associated GeometryElement when the value is non-negative and not duplicated by other GeometryObjects in the associated GeometryElement.
The extracted geometry is returned to you as Autodesk.Revit.DB.GeometryElement. You can iterate through the geometry members of that element by using the GetEnumerator() method.
Typically, the objects returned at the top level of the extracted geometry will be one of:
* [Solids, Faces and Edges](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html) a boundary representation made up of faces and edges
* [Meshes](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Meshes_html.html) a 3D array of triangles
* [Curves](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html) a bounded 3D curve
* [Points](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Points_html.html) a visible point datum at a given 3D location
* [PolyLines](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_PolyLines_html.html) a series of line segments defined by 3D points
* [GeometryInstances](./GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_GeometryInstances_html.html) an instance of a geometric element positioned within the element
This figure illustrates the hierarchy of objects found by geometry extraction.
**Pages in this section**
* [Curves](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Curves_html.html)
* [GeometryInstances](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_GeometryInstances_html.html)
* [Meshes](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Meshes_html.html)
* [Points](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Points_html.html)
* [PolyLines](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_PolyLines_html.html)
* [Solids, Faces and Edges](GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html)
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,353 @@
# Geometry Helper Classes
# Geometry Helper Classes
Several Geometry Helper classes are in the API. The Helper classes are used to describe geometry information for certain elements, such as defining a CropBox for a view using the BoundingBoxXYZ class.
* BoundingBoxXYZ - A 3D rectangular box used in cases such as defining a 3D view section area.
* Transform - Transforming the affine 3D space.
* Reference - A stable reference to a geometric object in a Revit model, which is used when creating elements like dimensions.
* Plane - A flat surface in geometry.
* Options - User preferences for parsing geometry.
* XYZ - Object representing coordinates in 3D space.
* UV - Object representing coordinates in 2D space.
* BoundingBoxUV - A 2D rectangle parallel to the coordinate axes.
## Transform
Transforms are limited to 3x4 transformations (Matrix) in the Revit application, transforming an object's place in the model space relative to the rest of the model space and other objects. The transforms are built from the position and orientation in the model space. Three direction Vectors (BasisX, BasisY and BasisZ properties) and Origin point provide all of the transform information. The matrix formed by the four values is as follows:
Applying the transformation to the point is as follows:
The Transform OfPoint method implements the previous function.
The Geometry.Transform class properties and methods are identified in the following sections.
### Identity
Transform the Identity.
CreateReflection()
### Reflect a specified plane.
**Figure 112: Wall Reflection relationship**
As the previous picture shows, one wall is mirrored by a reference plane. The CreateReflection() method needs the geometry plane information for the reference plane.
**Code Region 20-8: Using the Reflection property**
---
private Transform Reflect(ReferencePlane refPlane)
{
Transform mirTrans = Transform.CreateReflection(refPlane.GetPlane());
return mirTrans;
}
### CreateRotation() and CreateRotationAtPoint()
Rotate by a specified angle around a specified axis at (0,0,0) or at a specified point.
### CreateTranslation()
Translate by a specified vector. Given a vector XYZ data, a transformation is created as follow:
### Determinant
Transformation determinant.
### HasReflection
This is a Boolean value that indicates whether the transformation produces a reflection.
### Scale
A value that represents the transformation scale.
### Inverse
An inverse transformation. Transformation matrix A is invertible if a transformation matrix B exists such that A _B = B_ A = I (identity).
### IsIdentity
Boolean value that indicates whether this transformation is an identity.
### IsTranslation
Boolean value that indicates whether this transformation is a translation.
Geometry.Transform provides methods to perform basal matrix operations.
### Multiply
Multiplies a transformation by a specified transformation and returns the result.
Operator* - Multiplies two specified transforms.
### ScaleBasis
Scales the basis vectors and returns the result.
### ScaleBasisAndOrigin
Scales the basis vectors and the transformation origin returns the result.
### OfPoint
Applies the transformation to the point. The Origin property is used.
### OfVector
Applies the transform to the vector. The Origin property is not used.
### AlmostEqual
Compares two transformations. AlmostEqual is consistent with the computation mechanism and accuracy in the Revit core code. Additionally, Equal and the == operator are not implemented in the Transform class.
The API provides several shortcuts to complete geometry transformation. The Transformed property in several geometry classes is used to do the work, as shown in the following table.
**Table 48: Transformed Methods**
**Class Name** | **Function Description**
---|---
Curve.get_Transformed(Transform transform) | Applies the specified transformation to a curve
GeometryElement.GetTransformed(Transform transform) | Transforms a copy of the geometry in the original element.
Profile.get_Transformed(Transform transform) | Transforms the profile and returns the result.
Mesh.get_Transformed(Transform transform) | Transforms the mesh and returns the result.
Note: The transformed method clones itself then returns the transformed cloned result.
In addition to these methods, the Instance class (which is the parent class for elements like family instances, link instances, and imported CAD content) has two methods which provide the transform for a given Instance . The GetTransform() method obtains the basic transform for the instance based on how the instance is placed, while GetTotalTransform() provides the transform modified with the true north transform, for instances like import instances.
## Reference
The Reference is very useful in element creation.
* Dimension creation requires references.
* The reference identifies a path within a geometric representation tree in a flexible manner.
* The tree is used to view specific geometric representation creation.
The API exposes four types of references based on different Pick pointer types. They are retrieved from the API in different ways:
1. For Point - Curve.GetEndPointReference method
2. For Curve (Line, Arc, and etc.) - Curve.Reference property
3. For Face - Face.Reference property
4. For Cut Edge - Edge.Reference property
Different reference types cannot be used arbitrarily. For example:
* The NewLineBoundaryConditions() method requires a reference for Line
* The NewAreaBoundaryConditions() method requires a reference for Face
* The NewPointBoundaryConditions() method requires a reference for Point.
The Reference.ConvertToStableRepresentation() method can be used to save a reference to a geometry object, for example a face, edge, or curve, as a string, and later in the same Revit session (or even in a different session where the same document is present) use ParseFromStableRepresentation() method to obtain an identical Reference using the string as input.
## Options
Geometry is typically extracted from the indexed property Element.Geometry. The original geometry of a beam, column or brace, before the instance is modified by joins, cuts, coping, extensions, or other post-processing, can be extracted using the FamilyInstance.GetOriginalGeometry() method. Both Element.Geometry and FamilyInstance.GetOriginalGeometry() accept an options class which you must supply. The options class customizes the type of output you receive based on its properties:
* ComputeReferences - Indicates whether to compute the geometry reference when retrieving geometry information. The default value is false, so if this property is not set to true, the reference will not be accessible.
* IncludeNonVisibleObjects - Indicates to also return geometry objects which are not visible in a default view.
* View - Gets geometry information from a specific view. Note that if a view is assigned, the detail level for this view will be used in place of "DetailLevel".
* DetailLevel - Indicates the preferred detail level. The default is Medium.
### ComputeReferences
If you set this property to false, the API does not compute a geometry reference. All Reference properties retrieved from the geometry tree return nothing. For more details about references, refer to the Reference section. This option cannot be set to true when used with FamilyInstance.GetOriginalGeometry().
### IncludeNonVisibleObjects
Most of the non-visible geometry is construction and conditional geometry that the user sees when editing the element (i.e., the center plane of a window family instance). The default for this property is false. However, some of this conditionally visible geometry represents real-world objects, such as insulation surrounding ducts in Revit, and it should be extracted.
### View
If users set the View property to a different view, the retrieved geometry information can be different. Review the following examples for more information:
1. In Revit, draw a stair in 3D view then select the Crop Region, Crop Region Visible, and Section Box properties in the 3D view. In the Crop Region, modify the section box in the 3D view to display a portion of the stair. If you get the geometry information for the stair using the API and set the 3D view as the Options.View property, only a part of the stair geometry can be retrieved. The following pictures show the stair in the Revit application (left) and one drawn with the API (right).
**Figure 113: Different section boxes display different geometry**
Draw a stair in Revit then draw a section as shown in the left picture. If you get the information for this stair using the API and set this section view as the Options.View property, only a part of the stair geometry can be retrieved. The stair drawn with the API is shown in the right picture.
**Figure 114: Retrieve Geometry section view**
### DetailLevel
The API defines three enumerations in Geometry.Options.DetailLevels. The three enumerations correspond to the three Detail Levels in the Revit application, shown as follows.
**Figure 115: Three detail levels**
Different geometry information is retrieved based on different settings in the DetailLevel property. For example, draw a beam in the Revit application then get the geometry from the beam using the API to draw it. The following pictures show the drawing results:
**Figure 116: Detail geometry for a beam**
## BoundingBoxXYZ
BoundingBoxXYZ defines a 3D rectangular box that is required to be parallel to any coordinate axis. Similar to the Instance class, the BoundingBoxXYZ stores data in the local coordinate space. It has a Transform property that transforms the data from the box local coordinate space to the model space. In other words, to get the box boundary in the model space (the same one in Revit), transform each data member using the Transform property. The following sections illustrate how to use BoundingBoxXYZ.
### Define the View Boundaries
BoundingBoxXYZ can be used to define the view boundaries through View.CropBox property. The following pictures use a section view to show how BoundingBoxXYZ is used in the Revit application.
**Figure 117: BoundingBoxXYZ in section view**
The dash lines in the previous pictures show the section view boundary exposed as the CropBox property (a BoundingBoxXYZ instance).
**Figure 118: Created section view**
The previous picture displays the corresponding section view. The wall outside the view boundary is not displayed.
### Define a Section Box
BoundingBoxXYZ is also used to define a section box for a 3D view retrieved from the View3D.GetSectionBox() method. Select the Section Box property in the Properties Dialog box. The section box is shown as follows:
**Figure 119: 3D view section box**
### Other Uses
* Defines a box around an element's geometry. (Element.BoundingBox Property). The BoundingBoxXYZ instance retrieved in this way is parallel to the coordinate axes.
* Used in the ViewSection.CreateDetail () method .
The following table identifies the main uses for this class.
**Table 49: BoundingBoxXYZ properties**
**Property Name** | **Usage**
---|---
Max/Min | Maximum/Minimum coordinates. These two properties define a 3D box parallel to any coordinate axis. The Transform property provides a transform matrix that can transform the box to the appropriate position.
Transform | Transform from the box coordinate space to the model space.
Enabled | Indicates whether the bounding box is turned on.
MaxEnabled/ MinEnabled | Defines whether the maximum/minimum bound is active for a given dimension.
* If the Enable property is false, these two properties should also return false.
<table cellpadding="4" cellspacing="0" summary="" id="GUID-78445211-E211-4E27-B080-BE9FA3C50631__TABLE_4B666584884A4DFCA168F8AADC62FAA6" class="table" frame="border" border="1" rules="all">
<tbody class="tbody">
<tr class="row">
<td class="entry" valign="top"><img src="../../../images/GUID-ADBBC034-E8AA-4A96-AE95-9D9F82DB5080-low.png"/></td>
<td class="entry" valign="top">If the crop view is turned on, both <b><i>MaxEnabled</i></b> property and <b><i>MinEnabled</i></b> property return true.
</td>
</tr>
<tr class="row">
<td class="entry" valign="top"><img src="../../../images/GUID-7050609C-8AAF-40C4-A9A8-F8920B6AD022-low.png"/></td>
<td class="entry" valign="top">If the crop view is turned off, both <b><i>MaxEnabled</i></b> property and <b><i>MinEnabled</i></b> property return false.
</td>
</tr>
</tbody>
</table>
* This property indicates whether the view's crop box face can be used to clip the element's view.
* If BoundingBoxXYZ is retrieved from the View3D.GetSectionBox() method, the return value depends on whether the Section Box property is selected in the 3D view Properties dialog box. If so, all Enabled properties return true.
* If BoundingBoxXYZ is retrieved from the Element.BoundingBox property, all the Enabled properties are true.
Bounds | Wrapper for the Max/Min properties.
BoundEnabled | Wrapper for the MaxEnabled/MinEnabled properties.
The following code sample illustrates how to rotate BoundingBoxXYZ to modify the 3D view section box.
**Code Region 20-9: Rotating BoundingBoxXYZ**
---
private void RotateBoundingBox(View3D view3d)
{
if (!view3d.IsSectionBoxActive)
{
TaskDialog.Show("Revit","The section box for View3D isn't active.");
return;
}
BoundingBoxXYZ box = view3d.GetSectionBox();
// Create a rotation transform to apply to the section box
XYZ origin = new XYZ(0, 0, 0);
XYZ axis = new XYZ(0, 0, 1);
// Rotate 30 degrees
Transform rotate = Transform.CreateRotationAtPoint(axis, Math.PI/6.0, origin);
// Transform the View3D's section box with the rotation transform
box.Transform = box.Transform.Multiply(rotate);
// Set the section box back to the view (requires an open transaction)
view3d.SetSectionBox(box);
}
## BoundingBoxUV
BoundingBoxUV is a value class that defines a 2D rectangle parallel to the coordinate axes. It supports the Min and Max data members. Together they define the BoundingBoxUV's boundary. BoundingBoxUV is retrieved from the View.Outline property which is the boundary view in the paper space view.
**Figure 120: View outline**
Two points define a BoundingBoxUV.
* Min point - The bottom-left endpoint.
* Max point - The upper-right endpoint.
**Figure 121: BoundingBoxUV Max and Min**
Note: BoundingBoxUV cannot present a gradient rectangle as the following picture
shows. **Figure 122: Gradient rectangle**
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,49 @@
# Geometry Utility Classes
# Geometry Utility Classes
A number of utility classes are available for working with geometry objects.
### HostObjectUtils
The HostObjectUtils class offers methods as a shortcut to locate certain faces of compound HostObjects. These utilities retrieve the faces which act as the boundaries of the object's CompoundStructure:
* HostObjectUtils.GetSideFaces() applicable to Walls and FaceWalls; you can obtain either the exterior or interior finish faces.
* HostObjectUtils.GetTopFaces() and HostObjectUtils.GetBottomFaces() applicable to roofs, floors, and ceilings.
### SolidUtils
The SolidUtils class contains methods to perform operations on solids.
* SolidUtils.Clone() - creates a new Solid which is a copy of the input Solid.
* SolidUtils.SplitVolumes() - takes a solid which includes disjoint enclosed volumes and returns newly created Solid objects representing each volume. If no splitting is necessary, the input solid is returned.
* SolidUtils.TessellateSolidOrShell() - triangulates a given input Solid (which can be one or more fully closed volumes, or an open shell). Returns a TriangulatedSolidOrShell object which allows access to the stored triangulated boundary component of a solid or a triangulated connected component of a shell.
* SolidUtils.CreateTransformed() - creates a new solid which is the transformation of the input solid.
* SolidUtils.ComputeIsTopologicallyClosed() and SolidUtils.ComputeIsGeometricallyClosed() run a computation to check the closure of the input solid or shell and the one or more components it contains.
### JoinGeometryUtils
The JoinGeometryUtils class contains methods for joining and unjoining elements, and for managing the order in which elements are joined. These utilities are not available for family documents.
* JoinGeometryUtils.AreElementsJoined() - determines whether two elements are joined.
* JoinGeometryUtils.GetJoinedElements() - returns all elements joined to given element.
* JoinGeometryUtils.JoinGeometry() - creates a join between two elements that share a comon face. The visible edge between the joined elements is removed. and the joined elements then share the same line weight and fill pattern.
* JoinGeometryUtils.UnjoinGeometry() - removes a join between two joined elements.
* JoinGeometryUtils.SwitchJoinOrder() - reverses the order in which two elements are joined. The cutting element becomes the cut element and vice versa.
* JoinGeometryUtils . IsCuttingElementInJoin() - determines whether the first of two joined elements is cutting the second element or vice versa.
### FacetingUtils
This class is used to convert a triangulated structure into a structure in which some of the triangles have been consolidated into quadrilaterals.
* FacetingUtils.ConvertTrianglesToQuads() - this method takes a TriangulationInterface (constructed from a TriangulatedSolidOrShell) as input and returns a collection of triangles and quadrilaterals representing the original triangulated object.
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,119 @@
# Room and Space Geometry
# Room and Space Geometry
The Revit API provides access to the 3D geometry of spatial elements (rooms and spaces).
The methods in SpatialElement:
* SpatialElement.GetDefaultLocation() - Allows user to get the default location of the spatial element. The default location is a point where a spatial element is placed when it is created automatically without specifying a point.
* SpatialElement.Recenter() - Allows user to move the spatial element to its default location.
The method in SpatialElementTag:
* SpatialElementTag.MoveToReferenceLocation() - Allows user to move the SpatialElementTag to the location of SpatialElement that the tag is associated with.
The SpatialElementGeometryCalculator class can be used to calculate the geometry of a spatial element and obtain the relationships between the geometry and the element's boundary elements. There are 2 options which can be provided to this utility:
* SpatialElementBoundaryLocation whether to use finish faces or boundary element centerlines for calculation.
* StoredFreeBoundaryFaces whether to include faces which dont map directly to a boundary element in the results.
The results of calculating the geometry are contained in the class SpatialElementGeometryResults. From the SpatialElementGeometryResults class, you can obtain:
* The Solid volume representing the geometry (GetGeometry() method)
* The boundary face information (a collection SpatialElementBoundarySubfaces)
Each subface offers:
* The face of the spatial element
* The matching face of the boundary element
* The subface (the portion of the spatial element face bounded by this particular boundary element)
* The subface type (bottom, top, or side)
Some notes about the use of this utility:
* The calculator maintains an internal cache for geometry it has already processed. If you intend to calculate geometry for several elements in the same project you should use a single instance of this class. Note that the cache will be cleared when any change is made to the document.
* Floors are almost never included in as boundary elements. Revit uses the 2D outline of the room to form the bottom faces and does not match them to floor geometry.
* Openings created by wall-cutting features such as doors and windows are not included in the returned faces.
* The geometry calculations match the capabilities offered by Revit. In some cases where Revit makes assumptions about how to calculate the volumes of boundaries of rooms and spaces, these assumptions will be present in the output of the utility.
The following example calculates a room's geometry and finds its boundary faces.
**Code Region: Face Area using SpatialElementGeometryCalculator**
---
public void SpaceArea(Document doc, Room room)
{
SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc);
// compute the room geometry
SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room);
// get the solid representing the room's geometry
Solid roomSolid = results.GetGeometry();
foreach (Face face in roomSolid.Faces)
{
double faceArea = face.Area;
// get the sub-faces for the face of the room
IList<SpatialElementBoundarySubface> subfaceList = results.GetBoundaryFaceInfo(face);
foreach (SpatialElementBoundarySubface subface in subfaceList)
{
if (subfaceList.Count > 1) // there are multiple sub-faces that define the face
{
// get the area of each sub-face
double subfaceArea = subface.GetSubface().Area;
// sub-faces exist in situations such as when a room-bounding wall has been
// horizontally split and the faces of each split wall combine to create the
// entire face of the room
}
}
}
}
The following example calculates a room's geometry and finds its the material of faces that belong to the elements that define the room.
**Code Region: Face Material using SpatialElementGeometryCalculator**
---
public void MaterialFromFace(Document doc)
{
string s = "";
UIDocument uidoc = new UIDocument(doc);
Room room = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element).ElementId) as Room;
SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
spatialElementBoundaryOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish;
SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc, spatialElementBoundaryOptions);
SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room);
Solid roomSolid = results.GetGeometry();
foreach (Face roomSolidFace in roomSolid.Faces)
{
foreach (SpatialElementBoundarySubface subface in results.GetBoundaryFaceInfo(roomSolidFace))
{
Face boundingElementface = subface.GetBoundingElementFace();
ElementId id = boundingElementface.MaterialElementId;
s += doc.GetElement(id).Name + ", id = " + id.Value.ToString() + "\n";
}
}
TaskDialog.Show("revit",s);
}
**Parent page:** [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html)

View File

@@ -0,0 +1,30 @@
# Geometry
# Geometry
The Autodesk.Revit.DB namespace contains many classes related to geometry and graphic-related types used to describe the graphical representation in the API. The geometry-related classes include:
* [GeometryObject class](./Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html) \- Includes classes derived from the GeometryObject class.
* [Geometry Helper Classes](./Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html) \- Includes classes derived from the APIObject class and value types.
* [Geometry Utility Classes](./Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Utility_Classes_html.html) \- Includes classes to create non-element geometry and to find intersections of solids.
* [Collection Classes](./Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Collection_Classes_html.html) \- Includes classes derived from the IEnumerable or IEnumerator interface.
In this section, you learn how to use various graphic-related types, how to retrieve geometry data from an element, how to transform an element, and more.
**Pages in this section**
* [Example: Retrieve Geometry Data from a Wall](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Example_Retrieve_Geometry_Data_from_a_Wall_html.html)
* [GeometryObject Class](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_html.html)
* [Geometry Helper Classes](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Helper_Classes_html.html)
* [Collection Classes](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Collection_Classes_html.html)
* [Example: Retrieve Geometry Data from a Beam](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Example_Retrieve_Geometry_Data_from_a_Beam_html.html)
* [Extrusion Analysis of a Solid](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Extrusion_Analysis_of_a_Solid_html.html)
* [Finding Geometry by Ray Projection](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Finding_geometry_by_ray_projection_html.html)
* [Geometry Utility Classes](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Geometry_Utility_Classes_html.html)
* [Room and Space Geometry](Geometry/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_Room_and_Space_Geometry_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,169 @@
# Element Material
# Element Material
One element can have several elements and components. For example, FamilyInstance has SubComponents and Wall has CompoundStructure which contain several CompoundStructureLayers. (For more details about SubComponents refer to the Family Instances section and refer to [Walls, Floors, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html) for more information about CompoundStructure.)
In the Revit Platform API, get an element's materials using the following guidelines:
* If the element contains elements, get the materials separately.
* If the element contains components, get the material for each component from the parameters or in specific way (see [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html) section in [Walls, Floors, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)).
* If the component's material returns null, get the material from the corresponding Element.Category sub Category.
### Material in a Parameter
If the Element object has a Parameter with a Definition whose GetDataType() method returns SpecTypeId.Reference.Material, you can get the element material from the Parameter. For example, a structural column FamilySymbol (a FamilyInstance whose Category is BuiltInCategory.OST_StructuralColumns) has the Structural Material parameter. Get the Material using the ElementId. The following code example illustrates how to get the structural column Material that has one component.
**Code Region: Getting an element material from a parameter**
---
public void GetMaterialFromParameter(Document document, FamilyInstance familyInstance)
{
foreach (Parameter parameter in familyInstance.Parameters)
{
Definition definition = parameter.Definition;
// material is stored as element id
if (parameter.StorageType == StorageType.ElementId)
{
if (definition.GetGroupTypeId() == GroupTypeId.Materials &&
definition.GetDataType() == SpecTypeId.Reference.Material)
{
Autodesk.Revit.DB.Material material = null;
Autodesk.Revit.DB.ElementId materialId = parameter.AsElementId();
if (materialId == ElementId.InvalidElementId)
{
//Invalid ElementId, assume the material is "By Category"
if (null != familyInstance.Category)
{
material = familyInstance.Category.Material;
}
}
else
{
material = document.GetElement(materialId) as Material;
}
TaskDialog.Show("Revit","Element material: " + material.Name);
break;
}
}
}
}
Note: If the material property is set to By Category in the UI, the ElementId for the material is ElementId.InvalidElementId and cannot be used to retrieve the Material object as shown in the sample code. Try retrieving the Material from Category as described in the next section.
Some material properties contained in other compound parameters are not accessible from the API. As an example, in the following figure, for System Family: Railing, the Rail Structure parameter's StorageType is StorageType.None. As a result, you cannot get material information in this situation.
**Figure 107: Rail structure property**
### Material and FamilyInstance
Beam, Column and Foundation FamilyInstances have another way to get their material using their StructuralMaterialId property. This property returns an ElementId which identifies the material that defines the instance's structural analysis properties.
**Code Region: Getting an element material from a family instance**
---
public Material GetFamilyInstanceMaterial(Document document, FamilyInstance beam)
{
Material material = document.GetElement(beam.StructuralMaterialId) as Material;
return material;
}
### Material and Category
Only model elements can have material.
From the Revit Manage tab, click SettingsObject Styles to display the Object Styles dialog box. Elements whose category is listed in the Model Objects tab have material information.
**Figure 108: Category material**
Only Model elements can have the Material property assigned. Querying Material for a category that corresponds to other than Model elements (e.g., Annotations or Imported) will therefore always result in a null. For more details about the Element and Category classifications, refer to [Elements Essentials](../../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Elements_Essentials_html.html).
If an element has more than one component, some of the Category.Subcategories correspond to the components.
In the previous Object Styles dialog box, the Windows Category and the Frame/Mullion and Glass subcategories are mapped to components in the windows element. In the following picture, it seems the window symbol Glass Pane Material parameter is the only way to get the window pane material. However, the value is By Category and the corresponding Parameter returns ElementId.InvalidElementId.
In this case, the pane's Material is not null and it depends on the Category OST_WindowsFrameMullionProjection's Material property which is a subcategory of the window's category, OST_Windows. If it returns null as well, the pane's Material is determined by the parent category OST_Windows. For more details, refer to [Element Material](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Element_Material_html.html).
**Figure 109: Window material**
### CompoundStructureLayer Material
You can get the CompoundStructureLayer object from HostObjAttributes. For more details, refer to [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html).
### Retrieve Element Materials
The following diagram shows the workflow to retrieve Element Materials:
**Figure 110: Getting Element Material workflow**
This workflow illustrates the following process:
* The workflow shows how to get the Material object (not Autodesk.Revit.DB.Structure.StructuralMaterialType enumerated type) that belongs to the element.
* There are two element classifications when retrieving the Material:
* HostObject with CompoundStructure - Get the Material object from the CompoundStructureLayer class MaterialId property.
* Others - Get the Material from the Parameters.
* When you get a null Material object or an invalid ElementId with a value of ElementId.InvalidElementId, try the Material from the corresponding category. Note that a FamilyInstance and its FamilySymbol usually have the same category.
* The more you know about the Element object, the easier it is to get the material. For example:
* If you know the Element is a beam, you can get the instance parameter Structural Material.
* If you know the element is a window, you can cast it to a FamilyInstance and get the FamilySymbol.
* After that you can get the Parameters such as Frame Exterior Material or Frame Interior Material to get the Material object. If you get null try to get the Material object from the FamilySymbol Category.
* Not all Element Materials are available in the API.
### Walkthrough: Get Window Materials
The following code illustrates how to get the Window Materials.
**Code Region: Getting window materials walkthrough**
---
public void GetWindowMaterial(Document document, FamilyInstance window)
{
FamilySymbol windowSymbol = window.Symbol;
Category category = windowSymbol.Category;
Autodesk.Revit.DB.Material frameExteriorMaterial = null;
Autodesk.Revit.DB.Material frameInteriorMaterial = null;
Autodesk.Revit.DB.Material sashMaterial = null;
// Check the parameters first
foreach (Parameter parameter in windowSymbol.Parameters)
{
switch (parameter.Definition.Name)
{
case "Frame Exterior Material":
frameExteriorMaterial = document.GetElement(parameter.AsElementId()) as Material;
break;
case "Frame Interior Material":
frameInteriorMaterial = document.GetElement(parameter.AsElementId()) as Material;
break;
case "Sash":
sashMaterial = document.GetElement(parameter.AsElementId()) as Material;
break;
default:
break;
}
}
// Try category if the material is set by category
if (null == frameExteriorMaterial)
frameExteriorMaterial = category.Material;
if (null == frameInteriorMaterial)
frameInteriorMaterial = category.Material;
if (null == sashMaterial)
sashMaterial = category.Material;
// Show the result because the category may have a null Material,
// the Material objects need to be checked.
string materialsInfo = "Frame Exterior Material: " + (null != frameExteriorMaterial ? frameExteriorMaterial.Name : "null") + "\n";
materialsInfo += "Frame Interior Material: " + (null != frameInteriorMaterial ? frameInteriorMaterial.Name : "null") + "\n";
materialsInfo += "Sash: " + (null != sashMaterial ? sashMaterial.Name : "null") + "\n";
TaskDialog.Show("Revit",materialsInfo);
}
**Parent page:** [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html)

View File

@@ -0,0 +1,190 @@
# General Material Information
# General Material Information
Before you begin the walkthrough, read through the following section for a better understanding of the Material class.
All Material objects can be retrieved using a Material class filter. Material objects are also available in Document, Category, Element, Face, and so on, and are discussed in the pertinent sections in this chapter. Wherever you get a material object, it is represented as the Material class.
### Properties
A material will have one or more aspects pertaining to rendering appearance, structure, or other major material category. Each aspect is represented by properties on the Material class itself or via one of its assets, structural or thermal. The StructuralAsset class represents the properties of a material pertinent to structural analysis. The ThermalAsset class represents the properties of a material pertinent to energy analysis.
**Code Region 19-3: Getting material properties**
---
private void ReadMaterialProps(Document document, Material material)
{
ElementId strucAssetId = material.StructuralAssetId;
if (strucAssetId != ElementId.InvalidElementId)
{
PropertySetElement pse = document.GetElement(strucAssetId) as PropertySetElement;
if (pse != null)
{
StructuralAsset asset = pse.GetStructuralAsset();
// Check the material behavior and only read if Isotropic
if (asset.Behavior == StructuralBehavior.Isotropic)
{
// Get the class of material
StructuralAssetClass assetClass = asset.StructuralAssetClass; // Get other material properties
// Get other material properties
double poisson = asset.PoissonRatio.X;
double youngMod = asset.YoungModulus.X;
double thermCoeff = asset.ThermalExpansionCoefficient.X;
double unitweight = asset.Density;
double shearMod = asset.ShearModulus.X;
if (assetClass == StructuralAssetClass.Metal)
{
double dMinStress = asset.MinimumYieldStress;
}
else if (assetClass == StructuralAssetClass.Concrete)
{
double dConcComp = asset.ConcreteCompression;
}
}
}
}
}
### Classification
The material classification relevant to structural analysis (i.e., steel, concrete, wood) can be obtained from the StructuralAssetClass property of the StructuralAsset associated with the material.
Note: The API does not provide access to the values of Concrete Type for Concrete material.
The material classification relevant to energy analysis (i.e., solid, liquid, gas) can be obtained from the ThermalMaterialType property of the ThermalAsset associated with the material.
### Other Properties
The material object properties identify a specific type of material including color, fill pattern, and more.
#### Properties and Parameter
Some Material properties are only available as a Parameter. A few, such as Color, are available as a property or as a Parameter using the BuiltInParameter MATERIAL_PARAM_COLOR.
#### Rendering Information
Collections of rendering data are organized into objects called Assets. You can obtain all available Appearance-related assets from the Application.Assets property. An appearance asset can be accessed from a material via the Material.AppearanceAssetId property.
The following figure shows the Appearance Library section of the Asset Browser dialog box, which shows how some rendering assets are displayed in the UI.
**Figure 106: Appearance Library**
The Materials sample application included with the SDK shows how to set the RenderApperance property to a material selected in a dialog. The dialog is populated with all the Asset objects in Application.Assets.
#### Editing properties of an Appearance Asset
Editing properties in an appearance Asset requires establishment of an edit scope. The class
Autodesk.Revit.DB.Visual.AppearanceAssetEditScope
allows an application to create and maintain an editing session for an appearance asset. The scope provides access to an editable Asset object whose properties may be changed. Once all of the desired changes have been made to the asset's properties, the edit scope should be committed, which causes the changes to be sent back into the document. (This is the only part of the process when a transaction must be opened).
The methods of this class are
* AppearanceAssetEditScope.Start() Starts the edit scope for the asset contained in a particular AppearanceAssetElement. The editable Asset is returned from this method.
* AppearanceAssetEditScope.Commit() Finishes the edit scope: all changes made during the edit scope will be committed. Provides an option to force the update of all open views.
* AppearanceAssetEditScope.Cancel() Cancels the edit scope and discards any changes.
##### Connected Assets
Connected assets are associated to properties in appearance assets, and represent subordinate objects encapsulating a collection of related properties. One example of a connected asset is the "Unified Bitmap" representing an image and its mapping parameters and values. AssetProperty offers methods to provide the ability to modify, add or delete the asset connected to a property:
* AssetProperty.GetSingleConnectedAsset() Gets the single connected asset of this property
* AssetProperty.RemoveConnectedAsset() Removes the single connected asset of this property
* AssetProperty.AddConnectedAsset (String schemaId) Create a new default asset of schema type and connects it to this property
* AssetProperty.AddCopyAsConnectedAsset() Connects the property to a copy of the asset
##### Schemas & Property names
Appearance asset properties are aligned with specific schemas. Each schema contains necessary properties which define how the appearance of the material will be generated. There are 14 standard material schemas:
* Ceramic
* Concrete
* Generic
* Glazing
* Hardwood
* MasonryCMU
* Metal
* MetallicPaint
* Mirror
* PlasticVinyl
* SolidGlass
* Stone
* WallPaint
* Water
In addition, there are 5 schemas representing "advanced" materials - these may be encountered as a result of import from other Autodesk products:
* AdvancedLayered
* AdvancedMetal
* AdvancedOpaque
* AdvancedTransparent
* AdvancedWood
Finally, there are 10 schemas used for the aspects of the connected assets:
* BumpMap
* Checker
* Gradient
* Marble
* Noise
* Speckle
* Tile
* UnifiedBitmap
* Wave
* Wood
The method
AssetProperty.IsValidSchemaIdentifier(String schemaName)
identifies if the input name is a valid name for a supported schema.
To assist in creating code accessing and manipulating the properties of a given schema, predefined properties have been introduced to allow a compile-time reference to a property name without requiring you to transcribe it as a string in your code. These predefined property names are available in static classes named similar to the schema names, above, e.g., Autodesk.Revit.DB.Visual.Ceramic.
##### Asset Utilities
The method Application.GetAssets(AssetType) returns a list of assets available to the session.
The method AppearanceAssetElement.Duplicate() creates a copy of an appearance asset element and the asset contained by it.
The operator Asset.operator[ ] accesses a particular AssetProperty associated to the given asset.
#### FillPattern
All FillPatterns in a document are available using a FilteredElementCollector filtering on class FillPatternElement. A FillPatternElement is an element that contains a FillPattern while the FillPattern class provides access to the pattern name and the set of FillGrids that make up the pattern.
There are two kinds of FillPatterns: Drafting and Model. In the UI, you can only set Drafting fill patterns to Material.CutForegroundPatternId or Material.CutBackgroundPatternId. The fill pattern type is exposed via the FillPattern.Target property. The following example shows how to change the material FillPattern.
**Code Region 19-4: Setting the fill pattern**
---
public void SetFillPattern(Document document, Material material)
{
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<ElementId> fillPatternElements = collector.OfClass(typeof(FillPatternElement)).ToElementIds();
foreach (ElementId fillPatternId in fillPatternElements)
{
material.CutForegroundPatternId = fillPatternId;
material.SurfaceForegroundPatternId = fillPatternId;
}
}
**Parent page:** [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html)

View File

@@ -0,0 +1,107 @@
# Material Management
# Material Management
You can use filtering to retrieve all materials in the document. Every Material object in the Document is identified by a unique name.
The following example illustrates how to use the material name to get material.
**Code Region 19-5: Getting a material by name**
---
public void MaterialByName(Document document)
{
FilteredElementCollector elementCollector = new FilteredElementCollector(document);
elementCollector.WherePasses(new ElementClassFilter(typeof(Material)));
IList<Element> materials = elementCollector.ToElements();
Material floorMaterial = null;
string floorMaterialName = "Default Floor";
foreach (Element materialElement in materials)
{
Material material = materialElement as Material;
if (floorMaterialName == material.Name)
{
floorMaterial = material;
break;
}
}
if (null != floorMaterial)
{
TaskDialog.Show("Revit","Material found.");
}
}
Note: To run the sample code, make sure the material name exists in your document. All material names for the current document are located under the Manage tab (Project Settings panel > Materials.)
### Creating Materials
There are two ways to create a new Material object in the API.
* Duplicate an existing Material.
* Add a new Material.
When using the Duplicate() method, the returned Material object is the same type as the original.
**Code Region 19-6: Duplicating a material**
---
private bool DuplicateMaterial(Material material)
{
bool duplicated = false;
//try to duplicate a new instance of Material class using duplicate method
//make sure the name of new material is unique in MaterailSet
string newName = "new" + material.Name;
Material myMaterial = material.Duplicate(newName);
if (null == myMaterial)
{
TaskDialog.Show("Revit", "Failed to duplicate a material!");
}
else
{
duplicated = true;
}
return duplicated;
}
Use the static method Material.Create() to add a new Material directly. No matter how it is applied, it is necessary to specify a unique name for the material and any assets belonging to the material. The unique name is the Material object key.
**Code Region 19-7: Adding a new Material**
---
public void CreateMaterial(Document document)
{
//Create the material
ElementId materialId = Material.Create(document, "My Material");
Material material = document.GetElement(materialId) as Material;
//Create a new property set that can be used by this material
StructuralAsset strucAsset = new StructuralAsset("My Property Set", StructuralAssetClass.Concrete);
strucAsset.Behavior = StructuralBehavior.Isotropic;
strucAsset.Density = 232.0;
//Assign the property set to the material.
PropertySetElement pse = PropertySetElement.Create(document, strucAsset);
material.SetMaterialAspectByPropertySet(MaterialAspect.Structural, pse.Id);
}
### Deleting Materials
To delete a material use:
* Document.Delete()
Document.Delete() is a generic method. See [Editing Elements](../../Basic_Interaction_with_Revit_Elements/Revit_API_Revit_API_Developers_Guide_Basic_Interaction_with_Revit_Elements_Editing_Elements_html.html) for details.
**Parent page:** [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html)

View File

@@ -0,0 +1,34 @@
# Painting the Face of an Element
# Painting the Face of an Element
The Paint tool functionality is available through the Revit API. Faces of elements such as walls, floors, and roofs can be painted with a material to change their appearance. It does not change the structure of the element.
The methods related to painting elements are part of the Document class. Document.Paint() applies a material to a specified face of an element. Document.RemovePaint() will remove the applied material. Additionally, the IsPainted() and GetPaintedMaterial() methods return information about the face of an element.
**Code Region: Paint faces of a wall**
---
// Paint any unpainted faces of a given wall
public void PaintWallFaces(Wall wall, ElementId matId)
{
Document doc = wall.Document;
GeometryElement geometryElement = wall.get_Geometry(new Options());
foreach (GeometryObject geometryObject in geometryElement)
{
if (geometryObject is Solid)
{
Solid solid = geometryObject as Solid;
foreach (Face face in solid.Faces)
{
if (doc.IsPainted(wall.Id, face) == false)
{
doc.Paint(wall.Id, face, matId);
}
}
}
}
}
**Parent page:** [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html)

View File

@@ -0,0 +1,21 @@
# Material
# Material
In the Revit Platform API, material data is stored and managed as an Element. Just as in the Revit UI, a material can have several assets associated with it, but only thermal and structural (referred to as Physical in the Revit UI) assets can be assigned using the API.
Some material features are represented by properties on the Material class itself, such as FillPattern, Color, or Render while others are available as properties of either a structural or thermal asset associated with the material.
In this chapter, you learn how to access material elements and how to manage the Material objects in the document. [Element Material](./Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Element_Material_html.html) provides a walkthrough showing how to get a window material.
**Pages in this section**
* [General Material Information](Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_General_Material_Information_html.html)
* [Material Management](Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Material_Management_html.html)
* [Element Material](Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Element_Material_html.html)
* [Material quantities](Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Material_quantities_html.html)
* [Painting the Face of an Element](Material/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_Painting_the_Face_of_an_Element_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,130 @@
# 3D Sketch
# 3D Sketch
3D Sketch is used to edit a family or create a 3D object. In the Revit Platform API, you can complete the 3D Sketch using the following classes.
* Extrusion
* Revolution
* Blend
* Sweep
In other words, there are four operations through which a 2D model turns into a 3D model. For more details about sketching in 2D, refer to [The 2D Sketch Class](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_The_2D_Sketch_Class_html.html).
## Extrusion
Revit uses extrusions to define 3D geometry for families. You create an extrusion by defining a 2D sketch on a plane; Revit then extrudes the sketch between a start and an end point.
Query the Extrusion Form object for a generic form to use in family modeling and massing. The Extrusion class has the following properties:
**Table 40: Extrusion Properties**
**Property** | **Description**
---|---
ExtrusionStart | Returns the Extrusion Start point. It is a Double type.
ExtrusionEnd | Returns the Extrusion End point. It is a Double type.
Sketch | Returns the Extrusion Sketch. It contains a sketch plane and some curves.
**Figure 81: Extrusion result**
## Revolution
The Revolve command creates geometry that revolves around an axis. You can use the revolve command to create door knobs or other knobs on furniture, a dome roof, or columns.
Query the Revolution Form object for a generic form to use in family modeling and massing. The Revolution class has the following properties:
**Table 41: Revolution Properties**
**Property** | **Description**
---|---
Axis | Returns the Axis. It is a ModelLine object.
EndAngle | Returns the End Angle. It is a Double type.
Sketch | Returns the Extrusion Sketch. It contains a SketchPlane and some curves.
EndAngle is consistent with the same parameter in the Revit UI. The following pictures illustrate the Revolution corresponding parameter, the sketch, and the result.
**Figure 82: Corresponding parameter**
**Figure 83: Revolution sketch**
**Figure 84: Revolution result**
Note:
* The Start Angle is not accessible using the Revit Platform API.
* If the End Angle is positive, the Rotation direction is clockwise. If it is negative, the Rotation direction is counterclockwise.
## Blend
The Blend command blends two profiles together. For example, if you sketch a large rectangle and a smaller rectangle on top of it, Revit blends the two shapes together.
Query the Blend Form object for a generic form to use in family modeling and massing. The Blend class has the following properties:
**Table 42: Blend Properties**
**Property** | **Description**
---|---
BottomSketch | Returns the Bottom Sketch. It is a Sketch object.
TopSketch | Returns the Top Sketch Blend. It is a Sketch object.
FirstEnd | Returns the First End. It is a Double type.
SecondEnd | Returns the Second End. It is a Double type.
The FirstEnd and SecondEnd property values are consistent with the same parameters in the Revit UI. The following pictures illustrate the Blend corresponding parameters, the sketches, and the result.
**Figure 85: Blend parameters in the UI**
**Figure 86: Blend top sketch and bottom sketch**
**Figure 87: Blend result**
## Sweep
The Sweep command sweeps one profile along a created 2D path or selected 3D path. The path may be an open or closed loop, but must pierce the profile plane.
Query the Sweep Form object for a generic form for use in family modeling and massing. The Sweep class has the following properties:
**Table 43: Sweep Properties**
**Property** | **Description**
---|---
Path3d | Returns the 3D Path Sketch. It is a Path3D object.
PathSketch | Returns the Plan Path Sketch. It is a Sketch object.
ProfileSketch | Returns the profile Sketch. It is a Sketch object.
EnableTrajSegmentation | Returns the Trajectory Segmentation state. It is a Boolean.
MaxSegmentAngle | Returns the Maximum Segment Angle. It is a Double type.
Creating a 2D Path is similar to other forms. The 3D Path is fetched by picking the created 3D curves.
**Figure 88: Pick the Sweep 3D path**
Note: The following information applies to Sweep:
* The Path3d property is available only when you use Pick Path to get the 3D path.
* PathSketch is available whether the path is 3D or 2D.
**Figure 89: Sweep profile sketch**
Note: The ProfileSketch is perpendicular to the path.
Segmented sweeps are useful for creating mechanical duct work elbows. Create a segmented sweep by setting two sweep parameters and sketching a path with arcs.
**Figure 90: Corresponding segment settings in the UI**
Note: The following information applies to segmented Sweeps:
* The parameters affect only arcs in the path.
* The minimum number of segments for a sweep is two.
* Change a segmented sweep to a non-segmented sweep by clearing the Trajectory Segmentation check box. The EnableTrajSegmentation property returns false.
* If the EnableTrajSegmentation property is false, the value of MaxSegmentAngle is the default 360°.
**Figure 91: Sweep result**
**Parent page:** [Sketching](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_html.html)

View File

@@ -0,0 +1,99 @@
# ModelCurve
# ModelCurve
ModelCurve represents model lines in the project. It exists in 3D space and is visible in all views.
The following pictures illustrate the four ModelCurve derived classes:
**Figure 92:ModelLine and ModelArc**
**Figure 93: ModelEllipse and ModelNurbSpline**
### Creating a ModelCurve
The key to creating a ModelCurve is to create the Geometry.Curve and SketchPlane where the Curve is located. Based on the Geometry.Curve type you input, the corresponding ModelCurve returned can be downcast to its correct type.
The following sample illustrates how to create a new model curve (ModelLine and ModelArc):
**Code Region 17-2: Creating a new model curve**
---
public void CreateModelCurves(Document document)
{
// get handle to application from document
Autodesk.Revit.ApplicationServices.Application application = document.Application;
// Create a geometry line in Revit application
XYZ startPoint = new XYZ(0, 0, 0);
XYZ endPoint = new XYZ(10, 10, 0);
Line geomLine = Line.CreateBound(startPoint, endPoint);
// Create a geometry arc in Revit application
XYZ end0 = new XYZ(1, 0, 0);
XYZ end1 = new XYZ(10, 10, 10);
XYZ pointOnCurve = new XYZ(10, 0, 0);
Arc geomArc = Arc.Create(end0, end1, pointOnCurve);
// Create a geometry plane in Revit application
XYZ origin = new XYZ(0, 0, 0);
XYZ normal = new XYZ(1, 1, 0);
Plane geomPlane = Plane.CreateByNormalAndOrigin(normal, origin);
// Create a sketch plane in current document
SketchPlane sketch = SketchPlane.Create(document, geomPlane);
// Create a ModelLine element using the created geometry line and sketch plane
ModelLine line = document.Create.NewModelCurve(geomLine, sketch) as ModelLine;
// Create a ModelArc element using the created geometry arc and sketch plane
ModelArc arc = document.Create.NewModelCurve(geomArc, sketch) as ModelArc;
}
### Members
GeometryCurve
The GeometryCurve property is used to get or set the model curve's geometry curve. Except for ModelHermiteSpline, you can get different Geometry.Curves from the four ModelCurves.
* Line
* Arc
* Ellipse
* Nurbspline
The following code sample illustrates how to get a specific Curve from a ModelCurve.
**Code Region 17-3: Getting a specific Curve from a ModelCurve**
---
public void GetCurve(ModelCurve modelCurve)
{
//get the geometry modelCurve of the model modelCurve
Autodesk.Revit.DB.Curve geoCurve = modelCurve.GeometryCurve;
if (geoCurve is Autodesk.Revit.DB.Line)
{
Line geoLine = geoCurve as Line;
}
}
The GeometryCurve property return value is a general Geometry.Curve object, therefore, you must use an As operator to convert the object type.
Note: The following information applies to GeometryCurve:
* In Revit you cannot create a Hermite curve but you can import it from other software such as AutoCAD. Geometry.Curve is the only geometry class that represents the Hermite curve.
* The SetPlaneAndCurve() method and the Curve and SketchPlane property setters are used in different situations.
* When the new Curve lies in the same SketchPlane, or the new SketchPlane lies on the same planar face with the old SketchPlane, use the Curve or SketchPlane property setters.
* If new Curve does not lay in the same SketchPlane, or the new SketchPlane does not lay on the same planar face with the old SketchPlane, you must simultaneously change the Curve value and the SketchPlane value using SetPlaneAndCurve() to avoid internal data inconsistency.
#### Line Styles
Line styles are represented by the GraphicsStyle class. All line styles for a ModelCurve are available from the GetLineStyleIds() method which returns a set of ElementIds of GraphicsStyle elements.
**Parent page:** [Sketching](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_html.html)

View File

@@ -0,0 +1,56 @@
# The 2D Sketch Class
# The 2D Sketch Class
The Sketch class represents enclosed curves in a plane used to create a 3D model. The key features are represented by the SketchPlane and CurveLoop properties.
When accessing the Family's 3D modeling information, Sketch objects are important to forming the geometry. For more details, refer to [3D Sketch](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_3D_Sketch_html.html).
SketchPlane is the basis for all 2D sketch classes such as ModelCurve and Sketch. SketchPlane is also the basis for 2D Annotation Elements such as DetailCurve. Both ModelCurve and DetailCurve have the SketchPlane property and need a SketchPlane in the corresponding creation method. SketchPlane is always invisible in the Revit UI.
Every ModelCurve must lie in one SketchPlane. In other words, wherever you draw a ModelCurve either in the UI or by using the API, a SketchPlane must exist. Therefore, at least one SketchPlane exists in a 2D view where a ModelCurve is drawn.
The 2D view contains the CeilingPlan, FloorPlan, and Elevation ViewTypes. By default, a SketchPlane is automatically created for all of these views. The 2D view-related SketchPlane Name returns the view name such as Level 1 or North.
**Figure 77: Pick a Plane to identify a new Work Plane**
When you specify a new work plane, you can select Pick a plane as illustrated in the previous picture. After you pick a plane, select a plane on a particular element such as a wall as the following picture shows. In this case, the SketchPlane.Name property returns a string related to that element. For example, in the following picture, the SketchPlane.Name property returns 'Generic - 8' the same as the Wall.Name property.
**Figure 78: Pick a Plane on a wall as Work Plane**
Note: A SketchPlane is different from a work plane because a work plane is visible and can be selected. It does not have a specific class in the current API, but is represented by the Element class. A work plane must be defined based on a specific SketchPlane. Both the work plane and SketchPlane Category property return null. Although SketchPlane is always invisible, there is always a SketchPlane that corresponds to a work plane. A work plane is used to express a SketchPlane in text and pictures.
The following information applies to SketchPlane members:
* ID, UniqueId, Name, and Plane properties return a value
* Parameters property is empty
* Location property returns a Location object
* Other properties return null
Plane contains the SketchPlane geometric information. SketchPlane sets up a plane coordinate system with Plane as the following picture illustrates:
**Figure 79: SketchPlane and Plane coordinate system**
The following code sample illustrates how to create a new SketchPlane:
**Code Region 17-1: Creating a new SketchPlane**
---
private SketchPlane CreateSketchPlane(UIApplication application)
{
//try to create a new sketch plane
XYZ newNormal = new XYZ(1, 1, 0); // the normal vector
XYZ newOrigin = new XYZ(0, 0, 0); // the origin point
// create geometry plane
Plane geometryPlane = Plane.CreateByNormalAndOrigin(newNormal, newOrigin);
// create sketch plane
SketchPlane sketchPlane = SketchPlane.Create(application.ActiveUIDocument.Document,geometryPlane);
return sketchPlane;
}
**Parent page:** [Sketching](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_html.html)

View File

@@ -0,0 +1,116 @@
# Sketching
# Sketching
Sketches define the shape of many elements in Revit such as:
* Ceiling
* Extrusion
* Filled Region
* Floor
* Opening
* Stair
* Railing
* Roof
In addition to Sketch Elements, ModelCurve is also described in this chapter. For more details about Element Classification, see [Element Classification](../Introduction/Elements_Essentials/Revit_API_Revit_API_Developers_Guide_Introduction_Elements_Essentials_Element_Classification_html.html) in the [Elements Essentials](../Introduction/Revit_API_Revit_API_Developers_Guide_Introduction_Elements_Essentials_html.html) section.
## Sketches of Ceilings, Floors, Walls, or Openings
### Getting the Sketch
You cannot retrieve a Sketch object by iterating the Document with a FilteredElementCollector. Instead, use these properties to get the element id of the element's sketch.
* Ceiling.SketchId
* Floor.SketchId
* Opening.SketchId
* Wall.SketchId
For a given sketch, you can get element (Floor, Wall...) that owns the sketch with the `Sketch.OwnerId` property. `Sketch.GetAllElements()` returns all elements (ModelCurve, ReferencePlane, Dimension) that belong to a sketch.
### Editing and Validating the Sketch
Use the `SketchEditScope` class to edit the sketch. While a Sketch editing session is active, you can add, delete or modify Sketch elements (curves, dimensions, reference planes). A transaction will be needed to make the changes. When you finish the session, the Sketch-based element will be updated.
Key methods include:
* SketchEditScope constructor - Creates a new SketchEditScope.
* Start() - Starts editing a particular sketch. After this is started only elements owned by the Sketch and new elements to be added to the Sketch may be modified
* StartWithNewSketch() - Because a valid sketch may not initially exist for some Revit elements (such as Walls or Analytical Elements), a valid sketch will need to be created before it can be edited.
* Commit() - Commits the changes.
* IsSketchEditingSupported() - Checks if a sketch can be edited with a SketchEditScope.
ElementTransformUtils.CopyElements(View, ICollection(ElementId), View, Transform, CopyPasteOptions) can be used to copy sketch members from a sketch to the main document.
Additional supported copy/paste cases:
* Copying within one Sketch - If there is an active sketch edit mode, you can now copy sketch members of the active sketch. The copied elements will be added to the active sketch.
* Copying between Sketches - Allows you to copy sketch members from one sketch to another. To do this, sketches must be parallel and the destination sketch must be in edit mode.
* Copying ModelCurves from the Document to a Sketch - Allows you to copy ModelCurves from the document to a sketch, if the sketch is in edit mode. To do this, the sketch plane must be parallel to the WorkPlane that ModelCurves are based on.
#### Boundary Validation
The `BoundaryValidation` class provides methods to validate curve loops for sketching:
* `IsValidHorizontalBoundary` identifies whether the provided curve loops create a valid horizontal boundary.
* `IsValidBoundaryOnView` checks that a curve loop boundary is valid on the view's sketch plane.
* `IsValidBoundaryOnSketchPlane` checks that a curve loop boundary is valid on a sketch plane.
**Code Region: Edit a Floor Sketch**
private void EditSketch(Floor floor)
{
// Delete all lines in the sketch & create two new arcs that form a circle
Document doc = floor.Document;
Sketch sketch = doc.GetElement(floor.SketchId) as Sketch;
using (SketchEditScope edit = new SketchEditScope(doc, "Edit Floor"))
{
edit.Start(floor.SketchId);
using (Transaction t = new Transaction(doc, "Edit Sketch"))
{
t.Start();
doc.Delete(sketch.GetAllElements());
doc.Create.NewModelCurve(
Arc.Create(sketch.SketchPlane.GetPlane(), 5, 0, Math.PI * 2),
sketch.SketchPlane);
t.Commit();
}
edit.Commit(new failuresPreprocessor());
}
}
private class failuresPreprocessor : IFailuresPreprocessor
{
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
{
return FailureProcessingResult.Continue;
}
}
**Pages in this section**
* [The 2D Sketch Class](Sketching/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_The_2D_Sketch_Class_html.html)
* [3D Sketch](Sketching/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_3D_Sketch_html.html)
* [ModelCurve](Sketching/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Sketching_ModelCurve_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,193 @@
# Creating and Editing Stairs
# Creating and Editing Stairs
### StairsEditScope
As with other types of elements in the Revit document, a Transaction is necessary to edit stairs and stairs components. However, to create new components such as runs and landings, or to create new stairs themselves, it is necessary to use an Autodesk.Revit.DB.StairsEditScope object which maintains a stairs-editing session.
StairsEditScope acts like a TransactionGroup. After a StairsEditScope is started, you can start transactions and edit the stairs. Individual transactions created inside StairsEditScope will not appear in the undo menu. All transactions committed during the edit mode will be merged into a single one which will bear the name passed into the StairsEditScope constructor.
StairsEditScope has two Start methods. One takes the ElementId for an existing Stairs object for which it starts a stairs-editing session. The second Start method takes the ElementIds for base and top levels and creates a new empty stairs element with a default stairs type in the specified levels and then starts a stairs edit mode for the new stairs.
After runs and landings have been added to the Stairs and editing is complete, call StairsEditScope.Commit() to end the stairs-editing session.
### Adding Runs
The StairsRun class has three static methods for creating new runs for a Stairs object:
* **CreateSketchedRun** \- Creates a sketched run by providing a group of boundary curves and riser curves.
* **CreateStraightRun** \- Creates a straight run.
* **CreateSpiralRun** \- Creates a spiral run by providing the center, start angle and included angle.
### Adding Landings
Either automatic or sketched landings can be added between two runs. The static method StairsLanding.CanCreateAutomaticLanding() will check whether two stairs runs meet restriction to create automatic landing(s). The static StairsLanding.CreateAutomaticLanding() method will return the Ids of all landings created between the two stairs runs.
The static StairsLanding.CreateSketchedLanding method creates a customized landing between two runs by providing the closed boundary curves of the landing. One of the inputs to the CreateSketchedLanding method is a double value for the base elevation. The elevation has following restriction:
* The base elevation is relative to the base elevation of the stairs.
* The base elevation will be rounded automatically to a multiple of the riser height.
* The base elevation should be equal to or greater than half of the riser height.
### Example
The following example creates a new Stairs object, two runs (one sketched, one straight) and a landing between them.
**Code Region: Creating Stairs, Runs and a Landing**
---
public class StairCreation
{
// FailurePreprocessor class required for StairsEditScope
class StairsFailurePreprocessor : IFailuresPreprocessor
{
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
{
// Use default failure processing
return FailureProcessingResult.Continue;
}
}
private ElementId CreateStairs(Document document, Level levelBottom, Level levelTop)
{
ElementId newStairsId = null;
using (StairsEditScope newStairsScope = new StairsEditScope(document, "New Stairs"))
{
newStairsId = newStairsScope.Start(levelBottom.Id, levelTop.Id);
using (Transaction stairsTrans = new Transaction(document, "Add Runs and Landings to Stairs"))
{
stairsTrans.Start();
// Create a sketched run for the stairs
IList<Curve> bdryCurves = new List<Curve>();
IList<Curve> riserCurves = new List<Curve>();
IList<Curve> pathCurves = new List<Curve>();
XYZ pnt1 = new XYZ(0, 0, 0);
XYZ pnt2 = new XYZ(15, 0, 0);
XYZ pnt3 = new XYZ(0, 10, 0);
XYZ pnt4 = new XYZ(15, 10, 0);
// boundaries
bdryCurves.Add(Line.CreateBound(pnt1, pnt2));
bdryCurves.Add(Line.CreateBound(pnt3, pnt4));
// riser curves
const int riserNum = 20;
for (int ii = 0; ii <= riserNum; ii++)
{
XYZ end0 = (pnt1 + pnt2) * ii / (double)riserNum;
XYZ end1 = (pnt3 + pnt4) * ii / (double)riserNum;
XYZ end2 = new XYZ(end1.X, 10, 0);
riserCurves.Add(Line.CreateBound(end0, end2));
}
//stairs path curves
XYZ pathEnd0 = (pnt1 + pnt3) / 2.0;
XYZ pathEnd1 = (pnt2 + pnt4) / 2.0;
pathCurves.Add(Line.CreateBound(pathEnd0, pathEnd1));
StairsRun newRun1 = StairsRun.CreateSketchedRun(document, newStairsId, levelBottom.Elevation, bdryCurves, riserCurves, pathCurves);
// Add a straight run
Line locationLine = Line.CreateBound(new XYZ(20, -5, newRun1.TopElevation), new XYZ(35, -5, newRun1.TopElevation));
StairsRun newRun2 = StairsRun.CreateStraightRun(document, newStairsId, locationLine, StairsRunJustification.Center);
newRun2.ActualRunWidth = 10;
// Add a landing between the runs
CurveLoop landingLoop = new CurveLoop();
XYZ p1 = new XYZ(15, 10, 0);
XYZ p2 = new XYZ(20, 10, 0);
XYZ p3 = new XYZ(20, -10, 0);
XYZ p4 = new XYZ(15, -10, 0);
Line curve_1 = Line.CreateBound(p1, p2);
Line curve_2 = Line.CreateBound(p2, p3);
Line curve_3 = Line.CreateBound(p3, p4);
Line curve_4 = Line.CreateBound(p4, p1);
landingLoop.Append(curve_1);
landingLoop.Append(curve_2);
landingLoop.Append(curve_3);
landingLoop.Append(curve_4);
StairsLanding newLanding = StairsLanding.CreateSketchedLanding(document, newStairsId, landingLoop, newRun1.TopElevation);
stairsTrans.Commit();
}
// A failure preprocessor is to handle possible failures during the edit mode commitment process.
newStairsScope.Commit(new StairsFailurePreprocessor());
}
return newStairsId;
}
}
The stairs resulting from the above example:
### Multistory Stairs
The MultistoryStairs class allows stairs to span multiple levels. A multistory stairs element may contain multiple stairs whose extents are governed by base and top levels.
This element will contain one or more Stairs elements. Stairs elements are either:
* a reference instance which is copied to each level covered by groups of identical stairs instances which share the same level height,
* or individual Stairs instances which are not connected to a group with the same level height.
By default, when adding new levels to the multistory stair, new stairs will be added to the group. For groups of duplicate stairs at different levels, the instances can be found as Subelements of the Stairs element.Stairs in a connected group can be edited together by modifying the associated Stairs instance. For specific floors that need special designs, stairs can be separated from the group with the Unpin method - changes made to the unpinned Stairs will not affect other any other instance in the element. The stairs can later be added back into the group with the Pin method, however any changes made to the stair will be lost since the stair's properties will be overridden by the group specifications.
**Code Region: Create Multistory Stairs**
---
public void CreateMultiStory(Stairs stairs)
{
Document doc = stairs.Document;
// create new MultistoryStairs
MultistoryStairs multistoryStairs = MultistoryStairs.Create(stairs);
// get all levels that can be connected to this multistoryStairs
IEnumerable<ElementId> levelIds = new FilteredElementCollector(doc).OfClass(typeof(Level)).Cast<Level>().Where(q => multistoryStairs.CanConnectLevel(q.Id))
.Select(q => q.Id);
// Connect the levels to the multistoryStairs
// The input to ConnectLevels is a HashSet or SortedSet, so a HashSet is created from the IEnumerable returned by FilteredElementCollector
multistoryStairs.ConnectLevels(new HashSet<ElementId>(levelIds));
}
When new stairs are created using the StairsEditScope.Start(ElementId, ElementId) method, they have default railings associated with them. However, the Railing.Create() method can be used to create new railings with the specified railing type on all sides of a stairs element for stairs without railings. Unlike run and landing creation which require the use of StairsEditScope, railing creation cannot be performed inside an open stairs editing session.
Since railings cannot be created for Stairs that already have railings associated with them, the following example deletes the existing railings associated with a Stairs object before creating new railings.
**Code Region: Create Railings**
---
private void CreateRailing(Document document, Stairs stairs)
{
using (Transaction trans = new Transaction(document, "Create Railings"))
{
trans.Start();
// Delete existing railings
ICollection<ElementId> railingIds = stairs.GetAssociatedRailings();
foreach (ElementId railingId in railingIds)
{
document.Delete(railingId);
}
// Find RailingType
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<ElementId> RailingTypeIds = collector.OfClass(typeof(RailingType)).ToElementIds();
Railing.Create(document, stairs.Id, RailingTypeIds.First(), RailingPlacementPosition.Treads);
trans.Commit();
}
}
**Parent page:** [Stairs and Railings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_html.html)

View File

@@ -0,0 +1,89 @@
# Railings
# Railings
The Autodesk.Revit.DB.Architecture.Railing class represents a railing element in an Autodesk Revit project. Although railings are associated with stairs, they can be associated with another host (such as a floor) or placed in space.
A Railing may be associated with up to five continuous rails and a RailingType which contains information about balusters and any number of non-continuous rails. Continuous rails may either be a top rail or a hand rail.
Railings represent the entire structure which includes continuous rails, non-continuous rails, balusters, and corner posts. Continuous rails refer to the top rail (TopRail class is a subclass of ContinuousRail) and the two possible hand rails (HandRail class is a subclass of ContinuousRail), each of which may appear on the left, right, or both left and right which counts as 2 of the 5 possible continuous rails. The continuous rails are directly accessible from the Railing via the TopRail property and the GetHandRails() method.
A non-continuous rail is a rail which runs parallel to the Railings path elevated by a height not greater than the railings height. A default-generated railings non-continuous rails are broken into sections by the balusters. A Railing may have zero or more rails and must have at least one baluster. The non-continuous rails and baluster placement are accessible via the RailingType.
Railings associated with stairs can be retrieved from the Stairs class with the GetAssociatedRailings() method. There are only a few properties and methods specific to railings such as the TopRail property which returns the ElementId of the top rail and Flipped which indicates if the Railing is flipped. The Railing.Flip() method flips the railing (for a stair-hosted railing, flip changes the railing position between placement on the treads or stringers), while the RemoveHost() method will remove the association between the railing and its host.
The following example retrieves all of the railings associated with a Stairs object and flips each railing that is the default railing that the system generates.
**Code Region: Working with Railings**
---
private void FlipDefaultRailings(Stairs stairs)
{
ICollection<ElementId> railingIds = stairs.GetAssociatedRailings();
Transaction trans = new Transaction(stairs.Document, "Flip Railings");
trans.Start();
foreach (ElementId railingId in railingIds)
{
Railing railing = stairs.Document.GetElement(railingId) as Railing;
if (railing.IsDefault == true)
{
railing.Flip();
}
}
trans.Commit();
}
The Railing class has a Create method which automatically creates new railings with the specified railing type on all sides of a stairs element. Railing creation is demonstrated in the [Creating and Editing Stairs](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Creating_and_Editing_Stairs_html.html) section.
The RailingType class represents the railing type used in the generation of a railing. It contains a number of properties about the railing, such as the height, lateral offset and type of the primary and secondary handrails as well as the top rail.
**Code Region: RailingType**
---
private void GetRailingType(Stairs stairs)
{
ICollection<ElementId> railingIds = stairs.GetAssociatedRailings();
foreach (ElementId railingId in railingIds)
{
Railing railing = stairs.Document.GetElement(railingId) as Railing;
RailingType railingType = stairs.Document.GetElement(railing.GetTypeId()) as RailingType;
// Format railing type info for display
string info = "Railing Type: " + railingType.Name;
info += "\nPrimary Handrail Height: " + railingType.PrimaryHandrailHeight;
info += "\nTop Rail Height: " + railingType.TopRailHeight;
TaskDialog.Show("Revit", info);
}
}
## Non-continuous Railings
RailingType.RailStructure
provide access to a collection of information about non-continuous rails that are part of a RailingType. The Autodesk.Revit.DB.Architecture.NonContinuousRailStructure returns a collection of Autodesk.Revit.DB.Architecture.NonContinuousRailInfo objects, each of which represents the properties needed to define a single non-continuous rail.
## Baluster Placement
RailingType.BalusterPlacement
provides access to the baluster and post placement information for a given railing type. The Autodesk.Revit.DB.Architecture.BalusterPlacement that it returns may contain instances of:
* Autodesk.Revit.DB.Architecture.BalusterPattern which represents the baluster pattern properties, containing 1 or more objects of the type BalusterInfo.
* Autodesk.Revit.DB.Architecture.PostPattern which represents the post pattern properties, containing up to 3 objects of the type BalusterInfo.
* Autodesk.Revit.DB.Architecture.BalusterInfo which represents the properties governing an instance of a single railing baluster or post.
To get the name used to reference the Host or Top Rail, use:
* BalusterInfo.GetReferenceNameForHost()
* BalusterInfo.GetReferenceNameForTopRail()
**Parent page:** [Stairs and Railings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_html.html)

View File

@@ -0,0 +1,65 @@
# Stairs Annotations
# Stairs Annotations
The StairsPath class can be used to annotate the slope direction and walk line of a stair. The static StairsPath.Create() method will create a new stairs path for the specified stairs with the specified stairs path type in a specific plan view in which the stairs must be visible.
The StairsPath class has the same properties that are available in the Properties window when editing a stairs path in the Revit UI, such as properties to set the up and down text along or whether the text should be shown at all. Additionally offsets for the up and down text can be specified as can an offset for the stairs path from the stairs centerline.
The following example finds a StairsPathType and a FloorPlan in the project and uses them to create a new StairsPath for a given Stairs.
**Code Region: Create a StairsPath**
---
private void CreateStairsPath(Document document, Stairs stairs)
{
Transaction transNewPath = new Transaction(document, "New Stairs Path");
transNewPath.Start();
// Find StairsPathType
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<ElementId> stairsPathIds = collector.OfClass(typeof(StairsPathType)).ToElementIds();
// Find a FloorPlan
ElementId planViewId = ElementId.InvalidElementId;
FilteredElementCollector viewCollector = new FilteredElementCollector(document);
ICollection<ElementId> viewIds = viewCollector.OfClass(typeof(View)).ToElementIds();
foreach (ElementId viewId in viewIds)
{
View view = document.GetElement(viewId) as View;
if (view.ViewType == ViewType.FloorPlan)
{
planViewId = view.Id;
break;
}
}
LinkElementId stairsLinkId = new LinkElementId(stairs.Id);
StairsPath.Create(stairs.Document, stairsLinkId, stairsPathIds.First(), planViewId);
transNewPath.Commit();
}
A StairsPath has a StairsPathType. Stair path types are available from 2 predefined system families: Automatic Up/Down Direction and Fixed Up Direction. The properties available for these two types are available as properties in the StairsPathType class, such as FullStepArrow and DistanceToCutMark.
The CutMarkType class represents a cut mark type in the Revit UI and it has properties to represent the same properties available when editing a cut mark type in the UI, such as CutLineAngle and CutLineExtension . It is associated with a StairsType object and can be retrieved using the BuiltInParameter STAIRSTYPE_CUTMARK_TYPE as shown below.
**Code Region: Getting the CutMarkType for Stairs**
---
private CutMarkType GetCutMark(Stairs stairs)
{
CutMarkType cutMarkType = null;
StairsType stairsType = stairs.Document.GetElement(stairs.GetTypeId()) as StairsType;
Parameter paramCutMark = stairsType.GetParameter(ParameterTypeId.StairstypeCutmarkType);
if (paramCutMark.StorageType == StorageType.ElementId) // should be an element id
{
ElementId cutMarkId = paramCutMark.AsElementId();
cutMarkType = stairs.Document.GetElement(cutMarkId) as CutMarkType;
}
return cutMarkType;
}
**Parent page:** [Stairs and Railings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_html.html)

View File

@@ -0,0 +1,175 @@
# Stairs Components
# Stairs Components
The Stairs class represents a stairs element in Revit and contains properties that represent information about the treads, risers, number of stories, as well as the height of the stairs and base and top elevation. Methods of the Stairs class can be used to get the stairs landing components, stairs run components and stairs supports.
The following example finds all of the Stairs that are by component and outputs some information on each of the Stairs to a Task Dialog. Note that this example uses a category filter with the BuiltInCategory.OST_Stairs which will return ElementIds for all stairs, therefore requiring a test to see if each ElementId represents a Stairs By Component before being cast to a Stairs class when retrieved from the document.
**Code Region: Getting stairs information**
---
private Stairs GetStairInfo(Document document)
{
Stairs stairs = null;
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<ElementId> stairsIds = collector.WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_Stairs).ToElementIds();
foreach (ElementId stairId in stairsIds)
{
if (Stairs.IsByComponent(document, stairId) == true)
{
stairs = document.GetElement(stairId) as Stairs;
// Format the information
String info = "\nNumber of stories: " + stairs.NumberOfStories;
info += "\nHeight of stairs: " + stairs.Height;
info += "\nNumber of treads: " + stairs.ActualTreadsNumber;
info += "\nTread depth: " + stairs.ActualTreadDepth;
// Show the information to the user.
TaskDialog.Show("Revit", info);
}
}
return stairs;
}
The StairsType class represents the type for a Stairs element. It contains information about the Stairs, such as the type of all runs and landings in the stairs object, types and offsets for supports on the left, right and middle of the stairs, and numerous other properties related to stair generation such as the maximum height of each riser on the stair element. The following example gets the StairsType for a Stairs element and displays some information about it in a TaskDialog.
**Code Region: Getting StairsType Info**
---
private void GetStairsType(Stairs stairs)
{
StairsType stairsType = stairs.Document.GetElement(stairs.GetTypeId()) as StairsType;
// Format stairs type info for display
string info = "Stairs Type: " + stairsType.Name;
info += "\nLeft Lateral Offset: " + stairsType.LeftLateralOffset;
info += "\nRight Lateral Offset: " + stairsType.RightLateralOffset;
info += "\nMax Riser Height: " + stairsType.MaxRiserHeight;
info += "\nMin Run Width: " + stairsType.MinRunWidth;
TaskDialog.Show("Revit", info);
}
### Runs
Stairs by component are composed of runs, landings and supports. Each of these items can be retrieved from the Stairs class. A run is represented in the Revit API by the StairsRun class. The following example gets each run for a Stairs object and makes sure that it begins and ends with a riser.
**Code Region: Working with StairsRun**
---
private void AddStartandEndRisers(Stairs stairs)
{
ICollection<ElementId> runIds = stairs.GetStairsRuns();
foreach (ElementId runId in runIds)
{
StairsRun run = stairs.Document.GetElement(runId) as StairsRun;
if (null != run)
{
run.BeginsWithRiser = true;
run.EndsWithRiser = true;
}
}
}
The StairsRun class provides access to run properties such as the StairsRunStyle (straight, winder, etc.), BaseElevation, TopElevation, and properties about the risers. There are also methods in the StairsRun class to access the supports hosted by the run, either all, or just those on the left or right side of the run boundaries. The GetStairsPath() method will return the curves representing the stairs path on the run, which are projected onto the base level of the stairs. The GetFootprintBoundary() method returns the run's boundary curves which are also projected onto the stairs' base level.
There are three static methods of the StairsRun class for creating new runs. These are covered in the [Creating and Editing Stairs](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Creating_and_Editing_Stairs_html.html) section.
The StairsRunType class represents the type of a StairsRun. It contains many properties about the treads and risers of the run as well as other information about the run. The following example gets the StairsRunType for the first run in a Stairs element and displays the riser and tread thicknesses along with the type's name.
**Code Region: Getting StairsRunType Info**
---
private void GetRunType(Stairs stairs)
{
ICollection<ElementId> runIds = stairs.GetStairsRuns();
ElementId firstRunId = runIds.First();
StairsRun firstRun = stairs.Document.GetElement(firstRunId) as StairsRun;
if (null != firstRun)
{
StairsRunType runType = stairs.Document.GetElement(firstRun.GetTypeId()) as StairsRunType;
// Format landing type info for display
string info = "Stairs Run Type: " + runType.Name;
info += "\nRiser Thickness: " + runType.RiserThickness;
info += "\nTread Thickness: " + runType.TreadThickness;
TaskDialog.Show("Revit", info);
}
}
### Landings
Landings are represented by the StairsLanding class. The following example finds the thickness for each landing of a Stairs object.
**Code Region: Working with StairsLanding**
---
private void GetStairLandings(Stairs stairs)
{
ICollection<ElementId> landingIds = stairs.GetStairsLandings();
string info = "Number of landings: " + landingIds.Count;
int landingIndex = 0;
foreach (ElementId landingId in landingIds)
{
landingIndex++;
StairsLanding landing = stairs.Document.GetElement(landingId) as StairsLanding;
if (null != landing)
{
info += "\nThickness of Landing " + landingIndex + ": " + landing.Thickness;
}
}
TaskDialog.Show("Revit", info);
}
Similar to StairsRun, StairsLanding has a GetStairsPath() method which returns the curves representing the stairs path on the landing projected onto the base level of the stairs and a GetFootprintBoundary() method which returns the landing's boundary curves, also projected onto the stairs' base level. Also similar to StairsRun, there is a method to get all of the supports hosted by the landing.
The StairsLanding class has a method to create a new landing between two runs. It is covered in the [Creating and Editing Stairs](./Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Creating_and_Editing_Stairs_html.html) section.
The StairsLandingType class represents a landing type in the Revit API. The StairsLandingType class has only a couple of properties specific to it, namely IsMonolithic which is true if the stairs landing is monolithic, and Thickness, representing the thickness of the stairs landing.
### StairsComponentConnection
Both StairsRun and StairsLanding have a GetConnections() method which provides information about connections among stairs components (run to run, or run to landing). The method returns a collection of StairsComponentConnection objects which have properties about each connection, including the connection type (to a landing, the start of a stairs run, or the end of a stairs run) and the Id of the connected stairs component.
### Supports
The Revit API does not expose a class for stairs supports. When getting the supports for Stairs, StairsRun, or a StairsLanding, the supports will be generic Revit Elements. The following example gets the names of all the supports for a Stairs object.
**Code Region: Getting Stairs Supports**
---
private void GetStairSupports(Stairs stairs)
{
ICollection<ElementId> supportIds = stairs.GetStairsSupports();
string info = "Number of supports: " + supportIds.Count;
int supportIndex = 0;
foreach (ElementId supportId in supportIds)
{
supportIndex++;
Element support = stairs.Document.GetElement(supportId);
if (null != support)
{
info += "\nName of support " + supportIndex + ": " + support.Name;
}
}
TaskDialog.Show("Revit", info);
}
**Parent page:** [Stairs and Railings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_html.html)

View File

@@ -0,0 +1,18 @@
# Stairs and Railings
# Stairs and Railings
### Stairs
Classes in the Revit API in the Autodesk.Revit.DB.Architecture namespace allow access to stairs and related components such as landings and runs. Stairs can be created or modified using the Revit API. The Stairs class represents stairs created "by component". Stair elements that were created by sketch cannot be accessed as a Stair object in the API. The static method Stairs.IsByComponent() can be used to determine if an ElementId represents stairs that were created by component.
**Pages in this section**
* [Creating and Editing Stairs](Stairs_and_Railings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Creating_and_Editing_Stairs_html.html)
* [Railings](Stairs_and_Railings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Railings_html.html)
* [Stairs Annotations](Stairs_and_Railings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Stairs_Annotations_html.html)
* [Stairs Components](Stairs_and_Railings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Stairs_and_Railings_Stairs_Components_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,13 @@
# SubElements
# SubElements
Several Revit elements can now contain a subdivision known as a Subelement. Subelements provide a way for parts of an element to behave as though they were real elements without incurring the overhead of adding more full elements to the model.
Many Revit features - for example parameters, schedules, and tags - were designed to operate on Elements. As a result, the Revit code needs to represent objects as Elements for them to participate in those features. This can lead to scalability problems, because every Element adds overhead and adding many Elements may decrease the performance of the model.
An alternative is to use Subelements. An element can expose a set of "Subelements" that it contains, specifying characteristics like their category and parameters, and certain Revit capabilities will treat those Subelements the same as ordinary Elements. For example, a Subelement may contribute geometry to the main element and may be able to be selected independently of its parent Element. It will possibly have its own (settable) type as well as an assigned category which can be different from its parent Element.
In the API, the new Subelement class is used to refer to either an Element or a specific subelement of a given Element. It is typically directly related to a Reference to either the Element or the specific subelement.
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,23 @@
# Surfaces
# Surfaces
The surface class represents the mathematical representation of a surface.
The surface class is not derived from the GeometryObject class and not bounded by edges or edge loops. A bounded surface in Revit is represented by the [Solids, Faces and Edges](Geometry/GeometryObject_Class/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_GeometryObject_Class_Solids_Faces_and_Edges_html.html) class.
Surface is the base class for more specific surfaces:
* Plane
* CylindricalSurface
* ConicalSurface
* RuledSurface
* RevolvedSurface
* HermiteSurface
* OffsetSurface - Represents a surface offset by a fixed distance in the direction of the originating surface normal. The signed offset distance is in the direction of the originating surfaces oriented normal vector at any given point, which can be the same as or opposite to the originating surfaces parametric normal vector.
These subclasses contain Create() methods and read-only properties and are suitable for constructing import geometry. See the [DirectShape](Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_DirectShape_html.html "This element type can store arbitrary geometry obtained from import operations or calculations in either a project or family document.") topic for examples of using Surfaces in geometry creation.
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)

View File

@@ -0,0 +1,120 @@
# CompoundStructure
# CompoundStructure
Describes the internal structure of a wall, floor, roof or ceiling.
Walls, floors, ceilings and roofs are all children of the API class HostObject. HostObject (and its related type class HostObjAttributes) provide read only access to the CompoundStructure. A compound structure consists a collection of ordered layers, proceeding from exterior to interior for a wall, or from top to bottom for a floor, roof or ceiling. The properties of these layers determine the thickness, material, and function of the overall structure of the associated wall, floor, roof or ceiling.
Layers can be accessed via the GetLayers() method and completely replaced using SetLayers().
Normally these layers are parallel and extend the entire host object with a fixed layer width. However, for walls the structure can also be “vertically compound”, where the layers vary at specified vertical distances from the top and bottom of the wall. Use CompoundStructure.IsVerticallyCompound to identify these. For vertically compound structures, the structure describes a vertical section via a rectangle which is divided into polygonal regions whose sides are all vertical or horizontal segments. A map associates each of these regions with the index of a layer in the CompoundStructure which determines the properties of that region.
It is possible to use the compound structure to find the geometric location of different layer boundaries. The method CompoundStructure.GetOffsetForLocationLine() provides the offset from the center location line to any of the location line options (core centerline, finish faces on either side, or core sides).
With the offset to the location line available, you can obtain the location of each layer boundary by starting from a known location and obtaining the widths of each bounding layer using CompoundStructure.GetLayerWidth().
Some notes about the use of CompoundStructure:
* The total width of the element is the sum of each CompoundStructureLayer's widths. You cannot change the element's total width directly but you can change it via changing the CompoundStructureLayer width. The index of the designated variable length layer (if assigned) can be obtained from CompoundStructure.VariableLayerIndex.
* You must set the CompoundStructure back to the HostObjAttributes instance (using the HostObjAttributes.SetCompoundStructure() method) in order for any change to be stored.
* Changes to the HostObjAttributes affects every instance in the current document. If you need a new combination of layers,you will need to create a new HostObjAttributes (use ElementType.Duplicate()) and assign the new CompoundStructure to it.
* The CompoundStructureLayer DeckProfileId, and DeckEmbeddingType, properties only work with Slab in the structural features of Revit. For more details, refer to [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html).
CompoundStructure Priority allows for the customization of CompoundStructure layer priority without needing to change its function, providing more flexibility in the design process. The functions:
* CompoundStructureLayer.LayerPriority
* CompoundStructure.GetLayerPriority()
* CompoundStructure.SetLayerPriority()
* CompoundStructure.IsValidLayerPriority()
* CompoundStructure.ResetLayerPriority()
* CompoundStructure.ResetAllLayersPriorities() provide read and write access to the priority values, plus the option to reset them to default.
## Material
Each CompoundStructureLayer in HostObjAttributes is typically displayed with some type of material. If CompoundStructureLayer.MaterialId returns -1, it means the Material is Category-related. For more details, refer to [Material](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Material_html.html). Getting the CompoundStructureLayer Material is illustrated in the following sample code:
**Code Region 11-5: Getting the CompoundStructureLayer Material**
---
public void GetWallLayerMaterial(Autodesk.Revit.DB.Document document, Wall wall)
{
// get WallType of wall
WallType aWallType = wall.WallType;
// Only Basic Wall has compoundStructure
if (WallKind.Basic == aWallType.Kind)
{
// Get CompoundStructure
CompoundStructure comStruct = aWallType.GetCompoundStructure();
Categories allCategories = document.Settings.Categories;
// Get the category OST_Walls default Material;
// use if that layer's default Material is <By Category>
Category wallCategory = allCategories.get_Item(BuiltInCategory.OST_Walls);
Autodesk.Revit.DB.Material wallMaterial = wallCategory.Material;
foreach (CompoundStructureLayer structLayer in comStruct.GetLayers())
{
Autodesk.Revit.DB.Material layerMaterial =
document.GetElement(structLayer.MaterialId) as Material;
// If CompoundStructureLayer's Material is specified, use default
// Material of its Category
if (null == layerMaterial)
{
switch (structLayer.Function)
{
case MaterialFunctionAssignment.Finish1:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsFinish1).Material;
break;
case MaterialFunctionAssignment.Finish2:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsFinish2).Material;
break;
case MaterialFunctionAssignment.Membrane:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsMembrane).Material;
break;
case MaterialFunctionAssignment.Structure:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsStructure).Material;
break;
case MaterialFunctionAssignment.Substrate:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsSubstrate).Material;
break;
case MaterialFunctionAssignment.Insulation:
layerMaterial =
allCategories.get_Item(BuiltInCategory.OST_WallsInsulation).Material;
break;
default:
// It is impossible to reach here
break;
}
if (null == layerMaterial)
{
// CompoundStructureLayer's default Material is its SubCategory
layerMaterial = wallMaterial;
}
}
TaskDialog.Show("Revit","Layer Material: " + layerMaterial);
}
}
}
Sometimes just the material from the "structural" layer is needed. Rather than looking at each layer for the one whose function is MaterialFunctionAssignment.Structure, use the CompoundStructure.StructuralMaterialIndex property to find the index of the layer whose material defines the structural properties of the type for the purposes of analysis.
Note: When calling SetLayers(), the StructuralMaterialIndex value will be cleared and need to be reset.
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,7 @@
# Curtains
# Curtains
Curtain walls, curtain systems, and curtain roofs are host elements for CurtainGrid objects. A curtain wall can have only one CurtainGrid, while curtain systems and curtain roofs may contain one or more CurtainGrids. For an example of how to create a CurtainSystem, see the CurtainSystem sample application included with the Revit SDK. For an example of creating a curtain wall and populating it with grid lines, see the CurtainWallGrid sample application.
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,100 @@
# Floors, Ceilings and Foundations
# Floors, Ceilings and Foundations
Floor, Ceiling and Foundation-related API items include:
**Table 28: Floors, Ceilings and Foundations in the API**
**Object** | **Element Type** | **ElementType Type** | **Element Creation** | **Other**
---|---|---|---|---
Floor | Floor | FloorType | Floor.Create() | FloorType.IsFoundationSlab = false
Ceiling | Ceiling | CeilingType | Ceiling.Create() | Category = OST_Ceilings
Wall Foundation | WallFoundation | WallFoundationType | No | Category = OST_StructuralFoundation
Isolated Foundation | FamilyInstance | FamilySymbol | NewFamilyInstance() | Category = OST_StructuralFoundation
Foundation Slab | Floor | FloorType | Floor.Create() | Category = OST_StructuralFoundation FloorType.IsFoundationSlab = true
Note: Floor and Ceiling derive from the class CeilingAndFloor.
The method Revit.DB.Ceiling.GetCeilingGridLine() returns the geometric representation of the ceiling grid, optionally including the ceiling boundary.
The following rules apply to Floor:
* Elements created from the Foundation Design bar have the same category, OST_StructuralFoundation, but correspond to different Classes.
* The FloorType IsFoundationSlab property sets the FloorType category to OST_StructuralFoundation or not.
When you retrieve FloorType to create a Floor or Foundation Slab with Floor.Create(), use the following methods:
**Figure 35: Create foundation and floor/slab**
Currently, the API does not provide access to the Floor Slope Arrow in the Floor class. However, when using the structural features of Revit, you can create a sloped slab with Floor.Create():
**Code Region 11-1: Floor.Create()**
---
public static Floor Create(Document document, IList<CurveLoop> profile, ElementId floorTypeId, ElementId levelId)
public static Floor Create(Document document, IList<CurveLoop> profile, ElementId floorTypeId, ElementId levelId, bool isStructural, Line slopeArrow, double slope
)
The Slope Arrow is created using the slopedArrow parameter.
**Figure 36: slopeArrow parameter in Floor.Create()**
The unit for the slope parameter in Floor.Create() is rise/run.
The Floor.FloorType property is an alternative to using the Floor.GetTypeId() method. For more information about structure-related members such as the GetSpanDirectionSymbolIds() method and the SpanDirectionAngle property, refer to the [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html) section.
When editing an Isolated Foundation in Revit, you can perform the following actions:
* You can pick a host, such as a floor. However, the FamilyInstance object Host property always returns null.
* When deleting the host floor, the Foundation is not deleted with it.
* The Foundation host is available from the Host (INSTANCE_FREE_HOST_PARAM) parameter.
* Use another related Offset (INSTANCE_FREE_HOST_OFFSET_PARAM) parameter to control the foundation offset from the host Element.
**Figure 37: Pick Host for FoundationSlab (FamilyInstance)**
Wall foundations are represented by the WallFoundation class in the API. The API provides limited access to both WallFoundation and WallFoundationType except when using the GetAnalyticalModel() method (refer to [Analytical Model](../../Discipline_Specific_Functionality/Structural_Engineering/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_Analytical_Model_html.html) in the [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html) section). For example, the attached wall is not available with the architectural features of Revit. Using the structural features of Revit, the relationship between the Wall class and the WallFoundation class is shown using the GetAnalyticalModelSupports() method in the AnalyticalModel class. For more details, refer to [Analytical Model](../../Discipline_Specific_Functionality/Structural_Engineering/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_Analytical_Model_html.html) in the [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html) section.
**Figure 38: Wall Foundation**
## Modifying Slabs
You can modify the form of slab-based elements using the SlabShapeEditor class. This class allows you to:
* Manipulate one or more of the points or edges on a selected slab-based element.
* Add points on the element to change the element's geometry.
* Add linear edges and split the existing face of a slab into smaller sub-regions.
* Remove the shape modifier and reset the element geometry back to the unmodified shape.
Here's an example of reverting a selected modified floor back to its original shape:
**Code Region 11-2: Reverting a slab's shape**
---
private void ResetSlabShapes(Autodesk.Revit.DB.Document document)
{
UIDocument uidoc = new UIDocument(document);
Selection choices = uidoc.Selection;
foreach (Autodesk.Revit.DB.Element elem in choices.GetElementIds().Select(q => document.GetElement(q)))
{
Floor floor = elem as Floor;
if (floor != null)
{
SlabShapeEditor slabShapeEditor = floor.GetSlabShapeEditor();
slabShapeEditor.ResetSlabShape();
}
}
}
For more detailed examples of using the SlabShapeEditor and related classes, see the SlabShapeEditing sample application included in the Revit SDK.
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,125 @@
# Opening
# Opening
In the Revit Platform API, the Opening object is derived from the Element object and contains all of the Element object properties and methods. To retrieve all Openings in a project, use Document.ElementIterator to find the Elements.Opening objects.
## General Properties
This section explains how to use the Opening properties.
* IsRectBoundary - Identifies whether the opening has a rectangular boundary.
* If true, it means the Opening has a rectangular boundary and you can get an `IList<XYZ>` collection from the Opening BoundaryRect property. Otherwise, the property returns null.
* If false, you can get a CurveArray object from the BoundaryCurves property.
* BoundaryCurves - If the opening boundary is not a rectangle, this property retrieves geometry information; otherwise it returns null. The property returns a CurveArray object containing the curves that represent the Opening object boundary.For more details about Curve, refer to [Geometry](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Geometry_html.html).
* BoundaryRect - If the opening boundary is a rectangle, you can get the geometry information using this property; otherwise it returns null.
* The property returns an `IList<XYZ>` collection containing the XYZ coordinates.
* The `IList<XYZ>` collection usually contains the rectangle boundary minimum (lower left) and the maximum (upper right) coordinates.
* Host - The host property retrieves the Opening host element. The host element is the element cut by the Opening object.
Note: Note If the Opening object's category is Shaft Openings, the Opening host is null.
The following example illustrates how to retrieve the existing Opening properties.
**Code Region 11-6: Retrieving existing opening properties**
---
private void Getinfo_Opening(Opening opening)
{
string message = "Opening:";
//get the host element of this opening
message += "\nThe id of the opening's host element is : " + opening.Host.Id.IntegerValue;
//get the information whether the opening has a rect boundary
//If the opening has a rect boundary, we can get the geometry information from BoundaryRect property.
//Otherwise we should get the geometry information from BoundaryCurves property
if (opening.IsRectBoundary)
{
message += "\nThe opening has a rectangular boundary.";
//array contains two XYZ objects: the max and min coords of boundary
IList<XYZ> boundaryRect = opening.BoundaryRect;
//get the coordinate value of the min coordinate point
XYZ point = opening.BoundaryRect[0];
message += "\nMin coordinate point:(" + point.X + ", "
+ point.Y + ", " + point.Z + ")";
//get the coordinate value of the Max coordinate point
point = opening.BoundaryRect[1];
message += "\nMax coordinate point: (" + point.X + ", "
+ point.Y + ", " + point.Z + ")";
}
else
{
message += "\nThe opening doesn't have a rectangular boundary.";
// Get curve number
int curves = opening.BoundaryCurves.Size;
message += "\nNumber of curves is : " + curves;
for (int i = 0; i < curves; i++)
{
Autodesk.Revit.DB.Curve curve = opening.BoundaryCurves.get_Item(i);
// Get curve start point
message += "\nCurve start point: " + XYZToString(curve.GetEndPoint(0));
// Get curve end point
message += "; Curve end point: " + XYZToString(curve.GetEndPoint(1));
}
}
TaskDialog.Show("Revit",message);
}
// output the point's three coordinates
string XYZToString(XYZ point)
{
return "(" + point.X + ", " + point.Y + ", " + point.Z + ")";
}
### Create Opening
In the Revit Platform API, use the Document.NewOpening() method to create an opening in your project. There are four method overloads you can use to create openings in different host elements:
**Code Region 11-7: NewOpening()**
---
//Create a new Opening in a beam, brace and column.
public Opening NewOpening(Element famInstElement, CurveArray profile, eRefFace iFace);
//Create a new Opening in a roof, floor and ceiling.
public Opening NewOpening(Element hostElement, CurveArray profile, bool bPerpendicularFace);
//Create a new Opening Element.
public Opening NewOpening(Level bottomLevel, Level topLevel, CurveArray profile);
//Create an opening in a straight wall or arc wall.
public Opening NewOpening(Wall wall, XYZ pntStart, XYZ pntEnd);
* Create an Opening in a Beam, Brace, or Column - Use to create an opening in a family instance. The iFace parameter indicates the face on which the opening is placed.
* Create a Roof, Floor, or Ceiling Opening - Use to create an opening in a roof, floor, or ceiling.
* The bPerpendicularFace parameter indicates whether the opening is perpendicular to the face or vertical.
* If the parameter is true, the opening is perpendicular to the host element face. See the following picture:
**Figure 39: Opening cut perpendicular to the host element face**
**Figure 40: Opening cut vertically to the host element**
* Create a New Opening Element - Use to create a shaft opening in your project. However, make sure the topLevel is higher than the bottomLevel; otherwise an exception is thrown.
* Create an Opening in a Straight Wall or Arc Wall - Use to create a rectangle opening in a wall. The coordinates of pntStart and pntEnd should be corner coordinates that can shape a rectangle. For example, the lower left corner and upper right corner of a rectangle. Otherwise an exception is thrown.
Note: Using the Opening command you can only create a rectangle shaped wall opening. To create some holes in a wall, edit the wall profile instead of the Opening command.
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,7 @@
# Other Elements
# Other Elements
Some Elements are not HostObjects (and don't have a specific class), but are special cases that can host other objects. For example, ramp and its associated element type, do not have specific classes in the API and instead are represented as Element and ElementType in the OST_Ramps category.
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,102 @@
# Roofs
# Roofs
Roofs in the Revit Platform API all derive from the RoofBase object. There are two classes:
* FootPrintRoof - represents a roof made from a building footprint
* ExtrusionRoof - represents roof made from an extruded profile
Both have a RoofType property that gets or sets the type of roof. This example shows how you can create a footprint roof based on some selected walls:
**Code Region 11-3: Creating a footprint roof**
---
public void CreateRoof(Document document)
{
// Before invoking this sample, select some walls to add a roof over.
// Make sure there is a level named "Roof" in the document.
// find the Roof level
FilteredElementCollector collector = new FilteredElementCollector(document);
collector.OfClass(typeof(Level));
var elements = from element in collector where element.Name == "Roof" select element;
Level level = elements.Cast<Level>().ElementAt<Level>(0);
collector = new FilteredElementCollector(document);
collector.OfClass(typeof(RoofType));
RoofType roofType = collector.FirstElement() as RoofType;
// Get the handle of the application
Autodesk.Revit.ApplicationServices.Application application = document.Application;
// Define the footprint for the roof based on user selection
CurveArray footprint = application.Create.NewCurveArray();
UIDocument uidoc = new UIDocument(document);
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
if (selectedIds.Count != 0)
{
foreach (ElementId id in selectedIds)
{
Element element = document.GetElement(id);
Wall wall = element as Wall;
if (wall != null)
{
LocationCurve wallCurve = wall.Location as LocationCurve;
footprint.Append(wallCurve.Curve);
continue;
}
ModelCurve modelCurve = element as ModelCurve;
if (modelCurve != null)
{
footprint.Append(modelCurve.GeometryCurve);
}
}
}
else
{
throw new Exception("You should select a curve loop, or a wall loop, or loops combination \nof walls and curves to create a footprint roof.");
}
ModelCurveArray footPrintToModelCurveMapping = new ModelCurveArray();
FootPrintRoof footprintRoof = document.Create.NewFootPrintRoof(footprint, level, roofType, out footPrintToModelCurveMapping);
ModelCurveArrayIterator iterator = footPrintToModelCurveMapping.ForwardIterator();
iterator.Reset();
while (iterator.MoveNext())
{
ModelCurve modelCurve = iterator.Current as ModelCurve;
footprintRoof.set_DefinesSlope(modelCurve, true);
footprintRoof.set_SlopeAngle(modelCurve, 0.5);
}
}
For an example of how to create an ExtrusionRoof, see the NewRoof sample application included with the Revit API SDK.
### Gutter and Fascia
Gutter and Fascia elements are derived from the HostedSweep class, which represents a roof. They can be created, deleted or modified via the API. To create these elements, use one of the Document.Create.NewFascia() or Document.Create.NewGutter() overrides. For an example of how to create new gutters and fascia, see the NewHostedSweep application included in the SDK samples. Below is a code snippet showing you can modify a gutter element's properties.
**Code Region 11-4: Modifying a gutter**
---
public void ModifyGutter(Document document)
{
UIDocument uidoc = new UIDocument(document);
foreach (Element elem in uidoc.Selection.GetElementIds().Select(q => document.GetElement(q)))
{
if (elem is Gutter)
{
Gutter gutter = elem as Gutter;
// convert degrees to rads:
gutter.Angle = 45.00 * Math.PI / 180;
TaskDialog.Show("Revit","Changed gutter angle");
}
}
}
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,25 @@
# Thermal Properties
# Thermal Properties
Certain assembly types such as Wall, Floor, Ceiling, Roof and Building Pad have calculated and settable thermal properties which are represented by the ThermalProperties class.
The ThermalProperties class has properties for the values shown above. Absorptance and Roughness are modifiable while HeatTransferCoefficient, ThermalResistance, and ThermalMass are read-only. The units for these calculated values are shown in the table below.
**Property** | **Unit**
---|---
HeatTransferCoefficient | watts per meter-squared kelvin (W/(m^2*K)
ThermalResistance | meter-squared kelvin per watt ((m^2*K)/Watt)
ThermalMass | kilogram feet-squared per second squared kelvin (kg ft^2/(s^2 K))
Thermal properties can be retrieved using the ThermalProperties property on the following types:
* WallType
* FloorType
* CeilingType
* RoofType
* BuildingPadType
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,105 @@
# Walls
# Walls
There are four kinds of Walls represented by the WallType.WallKind enumeration:
* Stacked
* Curtain
* Basic
* Unknown
The Wall and WallType class work with the Basic wall type while providing limited function to the Stacked and Curtain walls. On occasion you need to check a Wall to determine the wall type. For example, you cannot get sub-walls from a Stacked Wall using the API. WallKind is read only and set by System Family.
The Wall.Flipped property and Wall.flip() method gain access to and control Wall orientation. In the following examples, a Wall is compared before and after calling the flip() method.
* The Orientation property before is (0.0, 1.0, 0.0).
* The Orientation property after the flip call is (0.0, -1.0, 0.0).
* The Wall Location Line (WALL_KEY_REF_PARAM) parameter is 3, which represents Finish Face: Interior in the following table.
* Taking the line as reference, the Wall is moved but the Location is not changed.
**Figure 33: Original wall**
**Figure 34: Wall after flip**
**Table 24: Wall Location Line**
**Location Line Value** | **Description**
---|---
0 | Wall Centerline
1 | Core Centerline
2 | Finish Face: Exterior
3 | Finish Face: Interior
4 | Core Face: Exterior
5 | Core Face: Interior
There are five static override methods in the Wall class to create a Wall:
**Table 25: Create() Overrides**
**Name** | **Description**
---|---
Create(Document, Curve, WallType, Level, Double, Double, Boolean, Boolean) | Creates a new rectangular profile wall within the project using the specified wall type, height, and offset.
Create(Document, IList Curve , Boolean) | Creates a non rectangular profile wall within the project using the default wall style.
Create(Document, Curve, ElementId, Boolean) | Creates a new rectangular profile wall within the project on the level specified by ElementId using the default wall style.
Create(Document, IList Curve , ElementId, ElementId, Boolean) | Creates a non rectangular profile wall within the project using the specified wall type.
Create(Document, IList Curve , ElementId, ElementId, Boolean, XYZ) | Creates a non rectangular profile wall within the project using the specified wall type and normal vector.
The WallType Wall Function (WALL_ATTR_EXTERIOR) parameter influences the created wall instance Room Bounding and Structural Usage parameter. The WALL_ATTR_EXTERIOR value is an integer:
**Table 26: Wall Function**
**Wall Function** | **Interior** | **Exterior** | **Foundation** | **Retaining** | **Soffit**
---|---|---|---|---|---
Value | 0 | 1 | 2 | 3 | 4
The following rules apply to Walls created by the API:
* If the input structural parameter is true or the Wall Function (WALL_ATTR_EXTERIOR) parameter is Foundation, the Wall StructuralUsage parameter is Bearing; otherwise it is NonBearing.
* The created Wall Room Bounding (WALL_ATTR_ROOM_BOUNDING) parameter is false if the Wall Function (WALL_ATTR_EXTERIOR) parameter is Retaining.
For more information about structure-related functions such as the AnalyticalModel property, refer to [Structural Engineering](../../Discipline_Specific_Functionality/Revit_API_Revit_API_Developers_Guide_Discipline_Specific_Functionality_Structural_Engineering_html.html).
## Wall Profile Sketch
These methods provide access to add and remove profile sketches:
* Wall.CreateProfileSketch()
* Wall.RemoveProfileSketch()
`Wall.CanHaveProfileSketch()` returns True if the wall supports profile sketch. Arc walls and elliptical walls are two wall geometries that do not support having an edited profile. Once a sketch is added, the profile sketch can be edited using `SketchEditScope`.
## Slanted and Tapered Walls
`Wall.CrossSection` lets you get and set a wall to a value of the `WallCrossSection` enum (`SingleSlanted`, `Vertical`, `Tapered`). Wall.IsWallCrossSectionValid() checks if a cross section is valid for a specific wall.
`Autodesk.Revit.DB.WidthMeasuredAt` and `Autodesk.Revit.DB.InsertOrientation` define the shape of the wall and behavior of inserts for non-vertical walls.
## Wall Wrapping
Wrapping for a specific wall end can be selectively enabled or disabled when the wall's end wrap is activated in the Wall Type dialog.
* `Wall.GetWrappingLocationAsReferences(int locationIndex)` \- Gets an array of references to faces at the location.
* `Wall.GetWrappingLocationAsCurveParameter(int locationIndex)` \- Gets the non-normalized (actual) curve parameter of the location.
* `Wall.GetValidWrappingLocationIndices()` \- Gets all valid locations for end wrapping. The valid wrapping locations include the wall's two ends and locations on vertical faces of openings or profiles without joins.
* `AllowWrappingAtLocation(int locationIndex)` \- Allows wrapping at either of the wall's ends (when using `locationIndex` = 0 or 1) or other wrapping locations at vertical faces of openings or profiles.
* `DisallowWrappingAtLocation(int locationIndex)` \- Disallows wrapping at the specificed location.
* `IsWrappingAtLocationAllowed(int locationIndex)` \- Indicates if wrapping is allowed at a specified location.
## Wall Attachments
The methods:
Wall.GetAttachmentIds() Wall.AddAttachment() Wall.RemoveAttachment(ElementId targetId) Wall.RemoveAttachment(ElementId targetId, AttachmentLocation attachmentLocation) Wall.IsValidTargetAttachment() provide access to the attachment settings for walls on their top or bottom (to specific model elements like roofs, floors, ceilings, toposolids, or other walls).
**Parent page:** [Walls, Floors, Ceilings, Roofs and Openings](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_html.html)

View File

@@ -0,0 +1,22 @@
# Walls, Floors, Ceilings, Roofs and Openings
# Walls, Floors, Ceilings, Roofs and Openings
Elements and the corresponding ElementTypes representing built-in place construction.
The following sections cover the classes associated with built-in place construction such as walls, floors, ceilings, roofs and openings and their corresponding properties.
**Pages in this section**
* [Walls](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Walls_html.html)
* [Floors, Ceilings and Foundations](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Floors_Ceilings_and_Foundations_html.html)
* [Roofs](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Roofs_html.html)
* [Curtains](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Curtains_html.html)
* [Other Elements](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Other_Elements_html.html)
* [CompoundStructure](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_CompoundStructure_html.html)
* [Opening](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Opening_html.html)
* [Thermal Properties](Walls_Floors_Ceilings_Roofs_and_Openings/Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_Walls_Floors_Ceilings_Roofs_and_Openings_Thermal_Properties_html.html)
**Parent page:** [Revit Geometric Elements](../Revit_API_Revit_API_Developers_Guide_Revit_Geometric_Elements_html.html)