Revit 二次开发——Analysis Visualization Framework

Revit 二次开发——Analysis Visualization Framework-BIMBANK

BIMBANK 导言:今天程序员辣翅给大家分享一下 Revit 中 Analysis Visualization Framework (下面简称 AVF)的使用心得。AVF 是主要用于将分析数据可视化的一个框架。分析显示的样式有如下图五种。

我们这次着重讨论下有色表面。使用的软件是 Revit 2018,不同的版本样式种类可能也会有不同。

Revit 二次开发——Analysis Visualization Framework-BIMBANK

我们以墙面为例来介绍一下这里的有色表面分析样式。实际用途可以为墙面形变分析或者受力分析等等。首先,按通常一样新建一个类继承 IExternalCommand,这里命名为 AvfCommand。为了方便说明,我们将所有功能都写在这个类里面。先提示用户选择要分析的墙面。

[Transaction(TransactionMode.Manual)]
class AvfCommand : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, refstring message, ElementSet elements)
{
UIDocument uidoc =commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;

//获取选择的墙面
Reference faceRef =uidoc.Selection.PickObject(ObjectType.Face, "请选择墙面");
Element wall = doc.GetElement(faceRef.ElementId);
Face face = wall.GetGeometryObjectFromReference(faceRef)as Face;

return Result.Succeeded;
}
}

在给所选墙面“涂”上分析颜色之前,我们需要先添加两个辅助方法SetDisplayStyleSetupSFM,分别用来设置好显示样式和SpatialFieldManager。SpatialFieldManager是用来管理分析数据的。

private void SetDisplayStyle(View view)
{
//确认当前视图中有没有我们的测试分析样式,有的话直接使用,否则我们新建样式
Document doc = view.Document;
ElementId id = AnalysisDisplayStyle.FindByName(doc, "测试分析样式");
if (ElementId.InvalidElementId == id)
{
//新建样式
using (Transaction t = new Transaction(doc))
{
t.Start("Create AVF Display Style");

//有色表面设置,这里我们只设置了不显示表面网格线
AnalysisDisplayColoredSurfaceSettingscoloredSurfaceSettings = newAnalysisDisplayColoredSurfaceSettings();
coloredSurfaceSettings.ShowGridLines = false;

//颜色设置,设置数据最大值和最小值的颜色,中间值会在这两者之间过渡
AnalysisDisplayColorSettings colorSettings = newAnalysisDisplayColorSettings();
colorSettings.MinColor = new Color(0, 255, 0);
colorSettings.MaxColor = new Color(255, 0, 0);

//图例设置,显示图例
AnalysisDisplayLegendSettings legendSettings = newAnalysisDisplayLegendSettings();
legendSettings.ShowLegend = true;

//创建显示样式并使用到当前视图
AnalysisDisplayStyle analysisDisplayStyle =AnalysisDisplayStyle.CreateAnalysisDisplayStyle(
doc, "测试分析样式", coloredSurfaceSettings, colorSettings,legendSettings);
view.AnalysisDisplayStyleId = analysisDisplayStyle.Id;

t.Commit();
}
}
else
{
//使用已有的样式
using (Transaction t = new Transaction(doc))
{
t.Start("Set AVF Display Style");
view.AnalysisDisplayStyleId = id;
t.Commit();
}
}
}

public SpatialFieldManager SetupSFM(View view, ReferencefaceRef)
{
//确认当前视图已设置了显示样式
if (view.AnalysisDisplayStyleId ==ElementId.InvalidElementId)
SetDisplayStyle(view);

SpatialFieldManager sfm =SpatialFieldManager.GetSpatialFieldManager(view);
if (null == sfm)
sfm = SpatialFieldManager.CreateSpatialFieldManager(view,1);

//通过faceRef我们在SpatialFieldManager中创建一个空白的原始的分析结果
//sfpIndex是一个成员变量,初始值为-1. 这里判断之前是否已经创建过分析结果,如果有就移除之前的
if (0 < sfpIndex)
{
sfm.RemoveSpatialFieldPrimitive(sfpIndex);
}
sfpIndex = sfm.AddSpatialFieldPrimitive(faceRef);

//注册AnalysisResultSchema, AnalysisResultSchema包含了所有分析结果的信息
//schemaId是一个成员变量,初始值为-1,用于避免重复注册
if (-1 != schemaId)
{
IList<int> results = sfm.GetRegisteredResults();
if (!results.Contains(schemaId))
{
schemaId = -1;
}
}
if (-1 == schemaId)
{
AnalysisResultSchema schema = new AnalysisResultSchema("测试分析", "测试分析");

List<string> unitNames = new List<string>(new string[1] {"mm" });
List<double> unitFactors = new List<double>(new double[1] { 1.0 });
schema.SetUnits(unitNames, unitFactors);
schemaId = sfm.RegisterResult(schema);
}
return sfm;
}

然后我们就可以给墙面“上色”了,添加PaintFace方法。

private void PaintFace(SpatialFieldManager sfm, Face face)
{
//通过墙面的BoundingBox,我们可以获得该墙面的最小和最大坐标点
//两者之间的所有点就是我们可以添加分析数据的点,根据实际数据选择合理的点
//这里我们简单的通过ustep和vstep遍历整个墙面
BoundingBoxUV bb = face.GetBoundingBox();
double umin = bb.Min.U;
double umax = bb.Max.U;
double ustep = 0.2 * (umax - umin);

double vmin = bb.Min.V;
double vmax = bb.Max.V;
double vstep = 0.2 * (vmax - vmin);

//遍历整个墙面,记录所有点和每个点对应的分析数据值
//这里我们给每个点随机匹配个值
IList<UV> uvPts = new List<UV>();
IList<ValueAtPoint> uvValues = new List<ValueAtPoint>();
List<double> vals = new List<double>(1);
vals.Add(0);
Random random = new Random();
for (double u = umin; u <= umax; u += ustep)
{
for (double v = vmin; v <= vmax; v += vstep)
{
UV uv = new UV(u, v);

//确认点在面上
if (face.IsInside(uv))
{
uvPts.Add(uv);
vals[0] = random.NextDouble();
uvValues.Add(new ValueAtPoint(vals));
}
}
}

//用设置好的点和值更新分析结果
FieldDomainPointsByUV fpts = newFieldDomainPointsByUV(uvPts);
FieldValues fvals = new FieldValues(uvValues);
sfm.UpdateSpatialFieldPrimitive(sfpIndex, fpts, fvals,schemaId);
}

最后在Execute方法中调用下PaintFace就完成了。

public Result Execute(ExternalCommandData commandData, refstring message, ElementSet elements)
{
UIDocument uidoc =commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;

//获取选择的墙面
Reference faceRef =uidoc.Selection.PickObject(ObjectType.Face, "请选择墙面");
Element wall = doc.GetElement(faceRef.ElementId);
Face face = wall.GetGeometryObjectFromReference(faceRef)as Face;

SpatialFieldManager sfm = SetupSFM(uidoc.ActiveView,faceRef);
PaintFace(sfm, face);

return Result.Succeeded;
}

运行测试结果如下。因为是固定间隔随机值,所以看着有点奇怪。

Revit 二次开发——Analysis Visualization Framework-BIMBANK

参考:https://github.com/jeremytammik/RvtFader

扫描二维码关注BIMBANK官方微信,及时获取最专业的BIM资讯:

发表评论

坐等沙发
相关文章
【敬邀】8月21日-22日,第八届工程建设行业互联网大会中亿丰数字专场
【敬邀】8月21日-22日,第八届工程建设…
逐梦赛场——2020年“中亿丰杯”江苏省建筑施工BIM技术应用职业技能竞赛圆满举办!
逐梦赛场——2020年“中亿丰杯”江苏省建筑…
2020年苏州市住建系统“红色工匠”职业技能竞赛之建筑施工BIM技术应用技能竞赛顺利举办!
2020年苏州市住建系统“红色工匠”职业技…
第十一届“创新杯”建筑信息模型(BIM)应用大赛结果的公示
第十一届“创新杯”建筑信息模型(BIM)应…
首个江苏省省标版“5G+智慧工地2.0平台”正式发布了!
首个江苏省省标版“5G+智慧工地2.0平台”…
【直播预告】第六届工程建设行业互联网大会9.13即将开幕!
【直播预告】第六届工程建设行业互联网…