知識點
yunyou.ke.qq.com有相關免費課程
元素Element的基礎概念、如何編輯元素
- 具體内容
- 元素Element基礎
元素在Revit裡面尤其重要,使用者能看見的大多數對象都是元素,比如牆、族、族類型、族執行個體、标高、軸網、視圖等。Revit中的大多數類都是繼承自元素。元素是可序列化的,即是可以儲存到RVT項目檔案中。
(1)相關類圖
- 族、族執行個體相關
- 模型元素相關
- 設定相關
- 二維元素
- 其他元素
- 如何擷取元素
1)通過ID擷取元素: 必須要知道ID才可以擷取到元素。
//============代碼片段3-1通過Id擷取元素============ ElementId levelId = new ElementId(766598); Element element = RevitDoc.GetElement(levelId); Level level = element as Level; if(level != null) { //使用level } |
2)通過過濾器來擷取元素(推薦使用)
//============代碼片段3-2 過濾所有外牆============ FilteredElementCollector filteredElements = new FilteredElementCollector(RevitDoc); ElementClassFilter classFilter = new ElementClassFilter(typeof(Wall)); filteredElements = filteredElements.WherePasses(classFilter); foreach (Wall wall in filteredElements) { // 擷取牆類型“功能”參數,它用來訓示牆是否為外牆。 var functionParameter = wall.WallType.get_Parameter(BuiltInParameter.FUNCTION_PARAM); if (functionParameter != null && functionParameter.StorageType == StorageType.Integer) { if (functionParameter.AsInteger() == (int)WallFunction.Exterior) { // 使用wall } } } |
- 通過選擇
//============代碼片段3-3 擷取被選元素============ [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class MyExternalCommand : Autodesk.Revit.UI.IExternalCommand { public Autodesk.Revit.UI.Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements) { if (commandData.Application.ActiveUIDocument != null) { foreach (Element selected in commandData.Application.ActiveUIDocument.Selection.Elements) { Wall wall = selected as Wall; if(wall != null) { //使用wall } } } return Autodesk.Revit.UI.Result.Succeeded; } } |
- 擷取和修改元素參數
每個元素都有參數,Element.Parameters擷取到所有的參數,然後周遊找到需要的參數。也可以通過Element. get_Paramete(參數)來取得到單個參數,括号裡面的“參數”,有四種選擇:string參數名字、BuiltInParameter參數枚舉、Definition參數定義和Guid參數的guid。
//============代碼片段3-4 擷取“長度”參數============ ParameterSet parameters = element.Parameters; foreach (Parameter parameter in parameters) { if(parameter.Definition.Name == "長度" && parameter.StorageType == StorageType.Double) { double length = parameter.AsDouble(); // 使用length break; } } //============代碼片段3-5 使用BuiltInParameter擷取長度============ Wall wall = null; //中間有一段代碼就是将wall指派。 Parameter parameterLength = wall.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH); if (parameterLength != null && parameterLength.StorageType == StorageType.Double) { double length = parameterLength.AsDouble(); // 使用length } //============代碼片段3-6 修改參數============直接調用對象的Set方法。 Parameter parameterBaseOffset = wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET); if (parameterBaseOffset != null && parameterBaseOffset.StorageType == StorageType.Double) { if (!parameterBaseOffset.IsReadOnly) { bool success = parameterBaseOffset.Set(10.0); if (!success) { // 更新錯誤報告 } } else { // 參數是隻讀的 } } //Revit除了内建的參數BuiltInParameter、還允許使用者定義自定義參數:共享參數和項目參數。 //對應的界面上的額菜單分别是“管理—共享參數”、“管理—項目參數”。 //============代碼片段3-7 擷取共享參數============ // 打開共享參數檔案 DefinitionFile definitionFile = RevitApp.OpenSharedParameterFile(); // 擷取參數組的集合 DefinitionGroups groups = definitionFile.Groups; foreach (DefinitionGroup group in groups) { // 擷取參數組内的參數定義 foreach (Definition definition in group.Definitions) { string name = definition.Name; ParameterType type = definition.ParameterType; // 對參數定義的其他操作 } } //============代碼片段3-8 建立共享參數============ string sharedParametersFilename = @"C:\shared-parameters.txt"; string groupName = "MyGroup"; string definitionName = "MyDefinition"; ParameterType parameterType = ParameterType.Text; CategorySet categorySet = new CategorySet(); Category wallCategory = RevitDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Walls); categorySet.Insert(wallCategory); bool instanceParameter = true; BuiltInParameterGroup parameterGroup = BuiltInParameterGroup.PG_DATA; if (!System.IO.File.Exists(sharedParametersFilename)) { try { System.IO.StreamWriter sw = System.IO.File.CreateText(sharedParametersFilename); sw.Close(); } catch (Exception) { throw new Exception("Can't create shared parameter file: " + sharedParametersFilename); } } // 設定共享參數檔案 RevitApp.SharedParametersFilename = sharedParametersFilename; // 打開共享參數檔案 DefinitionFile definitionFile = RevitApp.OpenSharedParameterFile(); if (definitionFile == null) { throw new Exception("Can not open shared parameter file!"); } // 擷取參數組的集合 DefinitionGroups groups = definitionFile.Groups; // 擷取參數組 DefinitionGroup group = groups.get_Item(groupName); if (null == group) { // 如果參數組不存在,則建立一個 group = groups.Create(groupName); } if (null == group) throw new Exception("Failed to get or create group: " + groupName); // 擷取參數定義 Definition definition = group.Definitions.get_Item(definitionName); if (definition == null) { // 如果參數定義不存在,則建立一個 definition = group.Definitions.Create(definitionName, parameterType); } // 調用不同的函數建立類型參數或者執行個體參數 ElementBinding binding = null; if (instanceParameter) { binding = RevitApp.Create.NewInstanceBinding(categorySet); } else { binding = RevitApp.Create.NewTypeBinding(categorySet); } // 把參數定義和類别綁定起來(下面的小節會提到“綁定”),元素的新的參數就建立成功了。 bool insertSuccess = RevitDoc.ParameterBindings.Insert(definition, binding, parameterGroup); if (!insertSuccess) { throw new Exception("Failed to bind definition to category"); } //============代碼片段3-9 擷取類别和參數的綁定============ BindingMap map = RevitDoc.ParameterBindings; DefinitionBindingMapIterator dep = map.ForwardIterator(); while (dep.MoveNext()) { Definition definition = dep.Key; // 擷取參數定義的基本資訊 string definitionName = definition.Name; ParameterType parameterType = definition.ParameterType; // 幾乎都可以轉型為InstanceBinding,筆者沒有碰到過其他情況,如有例外,請聯系我們。 InstanceBinding instanceBinding = dep.Current as InstanceBinding; if (instanceBinding != null) { // 擷取綁定的類别清單 CategorySet categorySet = instanceBinding.Categories; } } //============代碼片段3-10 判斷共享參數和項目參數============ Parameter parameter; InternalDefinition definition = parameter.Definition as InternalDefinition; bool isSharedParameter = parameter.IsShared; //共享參數 bool isProjectParameter = definition.BuiltInParameter == BuiltInParameter.INVALID && !parameter.IsShared; //項目參數 //============代碼片段3-11 擷取分析模型的幾何資訊============ Element element = RevitDoc.GetElement(new ElementId(183554)); if (element == null) return; AnalyticalModel analyticalModel = element.GetAnalyticalModel(); if(analyticalModel.IsSingleCurve()) { Curve curve = analyticalModel.GetCurve(); // work with curve } else if(analyticalModel.IsSinglePoint()) { XYZ p = analyticalModel.GetPoint(); // work with point } else { IList<Curve> curves = analyticalModel.GetCurves(AnalyticalCurveType.ActiveCurves); // work with curves } //============代碼片段3-12 放置類型為"0762 x 2032 mm"的門============ string doorTypeName = "0762 x 2032 mm"; FamilySymbol doorType = null; // 在文檔中找到名字為"0762 x 2032 mm"的門類型 ElementFilter doorCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors); ElementFilter familySymbolFilter = new ElementClassFilter(typeof(FamilySymbol)); LogicalAndFilter andFilter = new LogicalAndFilter(doorCategoryFilter, familySymbolFilter); FilteredElementCollector doorSymbols = new FilteredElementCollector(RevitDoc); doorSymbols = doorSymbols.WherePasses(andFilter); bool symbolFound = false; foreach (FamilySymbol element in doorSymbols) { if (element.Name == doorTypeName) { symbolFound = true; doorType = element; break; } } // 如果沒有找到,就加載一個族檔案 if (!symbolFound) { string file = @"C:\ProgramData\Autodesk\RVT 2014\Libraries\Chinese_INTL\門\M_單-嵌闆 4.rfa"; Family family; bool loadSuccess = RevitDoc.LoadFamily(file, out family); if (loadSuccess) { foreach (ElementId doorTypeId in family.GetValidTypes()) { doorType = RevitDoc.GetElement(doorTypeId) as FamilySymbol; if (doorType != null) { if (doorType.Name == doorTypeName) { break; } } } } else { Autodesk.Revit.UI.TaskDialog.Show("Load family failed", "Could not load family file '" + file + "'"); } } // 使用族類型建立門 if (doorType != null) { // 首先找到線形的牆 ElementFilter wallFilter = new ElementClassFilter(typeof(Wall)); FilteredElementCollector filteredElements = new FilteredElementCollector(RevitDoc); filteredElements = filteredElements.WherePasses(wallFilter); Wall wall = null; Line line = null; foreach (Wall element in filteredElements) { LocationCurve locationCurve = element.Location as LocationCurve; if (locationCurve != null) { line = locationCurve.Curve as Line; if (line != null) { wall = element; break; } } } // 在牆的中心位置建立一個門 if (wall != null) { XYZ midPoint = (line.get_EndPoint(0) + line.get_EndPoint(1)) / 2; Level wallLevel = RevitDoc.GetElement(wall.LevelId) as Level; //建立門:傳入标高參數,作為門的預設标高 FamilyInstance door = RevitDoc.Create.NewFamilyInstance(midPoint, doorType, wall, wallLevel, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); Autodesk.Revit.UI.TaskDialog.Show("Succeed", door.Id.ToString()); Trace.WriteLine("Door created: " + door.Id.ToString()); } else { Autodesk.Revit.UI.TaskDialog.Show("元素不存在", "沒有找到符合條件的牆"); } } else { Autodesk.Revit.UI.TaskDialog.Show("族類型不存在", "沒有找到族類型'" + doorTypeName + "'"); } //============代碼片段3-13 建立拉伸實體族============ //建立族文檔 Document familyDoc = RevitApp.NewFamilyDocument(@"C:\ProgramData\Autodesk\RVT 2014\Family Templates\Chinese\公制正常模型.rft"); using (Transaction transaction = new Transaction(familyDoc)) { transaction.Start("Create family"); CurveArray curveArray = new CurveArray(); curveArray.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(5, 0, 0))); curveArray.Append(Line.CreateBound(new XYZ(5, 0, 0), new XYZ(5, 5, 0))); curveArray.Append(Line.CreateBound(new XYZ(5, 5, 0), new XYZ(0, 5, 0))); curveArray.Append(Line.CreateBound(new XYZ(0, 5, 0), new XYZ(0, 0, 0))); CurveArrArray curveArrArray = new CurveArrArray(); curveArrArray.Append(curveArray); //建立一個拉伸實體 familyDoc.FamilyCreate.NewExtrusion(true, curveArrArray, SketchPlane.Create(familyDoc, RevitApp.Create.NewPlane(new XYZ(0, 0, 1), XYZ.Zero)), 10); //建立一個族類型 familyDoc.FamilyManager.NewType("MyNewType"); transaction.Commit(); familyDoc.SaveAs("MyNewFamily.rfa"); familyDoc.Close(); } //============代碼片段3-14 複制牆類型============ Wall wall = RevitDoc.GetElement(new ElementId(185521)) as Wall; WallType wallType = wall.WallType; ElementType duplicatedWallType = wallType.Duplicate(wallType.Name + " (duplicated)"); |
四、總結
1、Revit API提供的元素相關的類。
2、如何擷取元素。
3、擷取和修改元素的參數。