C# Revit二次开发基础/核心编程--- 元素Element(基础、编辑)

一、本节课程
C# Revit二次开发基础/核心编程--- 元素Element(基础、编辑)

二、本节要讲解的知识点

    元素Element的基础概念、如何编辑元素

  • 具体内容
  1. 元素Element基础

元素在Revit里面尤其重要,用户能看见的大多数对象都是元素,比如墙、族、族类型、族实例、标高、轴网、视图等。Revit中的大多数类都是继承自元素。元素是可序列化的,即是可以保存到RVT项目文件中。

(1)相关类图

  1. 族、族实例相关

  1. 模型元素相关

  1. 设置相关

  1. 二维元素

  1. 其他元素

  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

      }

   }

}

  1. 通过选择

 

//============代码片段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;

   }

}

  1. 获取和修改元素参数

每个元素都有参数,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、获取和修改元素的参数。

猜你喜欢

转载自blog.csdn.net/yunyouxy/article/details/82917833