前言
自己研究了一圈材质之后,在官方文档里面翻了一下,发现也有一些介绍,整理一下。
我研究的参考:
Revit API: Material 材质
Revit API: 材质- 参考官方文档(一)
内容
材质的创建、查询、复制操作。
参考:
Material Management
Element Material
查询
通过材质名称查询和从构件开始进行查询。
通过材质名称查询
用过滤器FilteredElementCollector
把所有材质typeof(Material)
都过滤出来,然后通过名称material.Name
来查找。
FilteredElementCollector elementCollector = new FilteredElementCollector(document);
elementCollector.WherePasses(new ElementClassFilter(typeof(Material)));
IList 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.");
}
从构件开始进行查询
查询:获取某个构件使用的材质。
Revit 中的构件可能会有多个组件或者包含了多个子构件。比如,族实例和复合类型的墙。
如果想通过 Revit API 来获取一个构件的材质,有几条规则:
- 如果一个构件包含多个子构件,那么就分别查询这些子构件的材质;
- 如果一个构件包含多个组件,那么就分别查询这些组件的材质;
- 如果构件或组件的材质是
null
,那么就是尝试从它们的类别Category
中查找材质,如果类别中子类别,那么从子类别中查找。
流程图
例子 1:查询族实例的材质
关键逻辑:
- 查找符合定义的参数:
definition.ParameterGroup
为BuiltInParameterGroup.PG_MATERIALS
,definition.ParameterType
为ParameterType.Material
,并且parameter.StorageType
为StorageType.ElementId
的参数; - 如果没有找到符合定义的参数,则从类别中查找
familyInstance.Category.Material
。
public void GetMaterial(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.ParameterGroup == BuiltInParameterGroup.PG_MATERIALS &&
definition.ParameterType == ParameterType.Material)
{
Autodesk.Revit.DB.Material material = null;
Autodesk.Revit.DB.ElementId materialId = parameter.AsElementId();
if (-1 == materialId.IntegerValue)
{
//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;
}
}
}
}
例子 2:查询族实例 Beam 的材质
如果确定族实例是 Beam 或者其它(Column and Foundation FamilyInstances)可以通过 API 获得 StructuralMaterialId 的族实例,也可以这样获取材质:
public Material GetFamilyInstanceMaterial(Document document, FamilyInstance beam)
{
Material material = document.GetElement(beam.StructuralMaterialId) as Material;
return material;
}
例子 3:获取窗户的材质
窗户有三个材质,分别为框架外部材质frameExteriorMaterial
、框架内部材质frameInteriorMaterial
和玻璃嵌板材质sashMaterial
。
查找的逻辑依然是参数优先,没有符合定义的参数,则从类别中查找:
public void GetMaterial(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);
}
创建材质
用静态方法 Material.Create()
可以创建材质。
//创建材质
ElementId materialId = Material.Create(document, "My Material");
Material material = document.GetElement(materialId) as Material;
//创建一个新的属性集
StructuralAsset strucAsset = new StructuralAsset("My Property Set", StructuralAssetClass.Concrete);
strucAsset.Behavior = StructuralBehavior.Isotropic;
strucAsset.Density = 232.0;
//把这个属性集和材质关联起来
PropertySetElement pse = PropertySetElement.Create(document, strucAsset);
material.SetMaterialAspectByPropertySet(MaterialAspect.Structural, pse.Id);
复制材质
用 Material.Duplicate()
来复制材质。
private bool DuplicateMaterial(Material material)
{
bool duplicated = false;
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;
}