C# Revit二次开发基础/核心编程--- 元素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 // 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、获取和修改元素的参数。