应用程序: DistanceToSurfaces
Revit平台: 所有
Revit版本: 2011.0
首次发布版本: 2011.0
编程语言: C#
技能水平: 高级
类别: 几何
类型: ExternalApplication
主题:使用动态模型更新在Revit模型中展示分析结果。
摘要:在启动时,外部应用程序会创建一个触发器,该触发器将在项目中的墙体、实体和族实例发生更改时执行。当出现这种情况时,Revit会计算从一个家族实例(sphere.rfa)到每个面的几个点的距离。这些距离用作分析可视化显示的值。
相关类:
Autodesk.Revit.DB.Analysis.FieldDomainPointsByUV
Autodesk.Revit.DB.Analysis.FieldValues
Autodesk.Revit.DB.Analysis.SpatialFieldManager
Autodesk.Revit.DB.BoundingBoxUV
Autodesk.Revit.DB.Events.DocumentOpenedEventArgs
Autodesk.Revit.DB.FaceArray
Autodesk.Revit.DB.FilteredElementCollector
Autodesk.Revit.DB.LocationPoint
Autodesk.Revit.DB.UpdaterRegistry
功能:
1. 在启动时,注册一个DocumentOpened事件。当打开一个文档时,
a.检查球体族是否存在
b.检查是否存在名为“AVF”的3D视图
c.创建一个GetChangeTypeGeometry触发器,当墙体、实体楼板或组件实例更改时触发
2. 当出现此触发器时,
a. 查找球的 XYZ 位置
b. 获取现有的空间字段管理器对象,如果不存在则创建一个
c. 创建一个包含项目中每个墙体或楼板的每个面的面数组,包括就地几何
d. 计算球体原点与每个面上的几个点之间的距离
e. 通过更新空间字段基元,在面上显示这些距离作为分析结果。
使用说明:
打开 DistanceToSurfaces.rvt
移动墙体、块体或球体族的任意实例
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
Command.cs
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Linq;
using System.Collections.Generic;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Analysis;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.AnalysisVisualizationFramework.CS
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class DistanceToSurfaces : IExternalApplication
{
public Result OnStartup(UIControlledApplication uiControlledApplication)
{
uiControlledApplication.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(docOpen);
return Result.Succeeded;
}
private void docOpen(object sender, DocumentOpenedEventArgs e)
{
Autodesk.Revit.ApplicationServices.Application app = sender as Autodesk.Revit.ApplicationServices.Application;
UIApplication uiApp = new UIApplication(app);
Document doc = uiApp.ActiveUIDocument.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.WherePasses(new ElementClassFilter(typeof(FamilyInstance)));
var sphereElements = from element in collector where element.Name == "sphere" select element;
if (sphereElements.Count() == 0)
{
TaskDialog.Show("Error", "Sphere family must be loaded");
return;
}
FamilyInstance sphere = sphereElements.Cast<FamilyInstance>().First<FamilyInstance>();
FilteredElementCollector viewCollector = new FilteredElementCollector(doc);
ICollection<Element> views = viewCollector.OfClass(typeof(View3D)).ToElements();
var viewElements = from element in viewCollector where element.Name == "AVF" select element;
if (viewElements.Count() == 0)
{
TaskDialog.Show("Error", "A 3D view named 'AVF' must exist to run this application.");
return;
}
View view = viewElements.Cast<View>().First<View>();
SpatialFieldUpdater updater = new SpatialFieldUpdater(uiApp.ActiveAddInId, sphere.Id, view.Id);
if (!UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId())) UpdaterRegistry.RegisterUpdater(updater);
ElementCategoryFilter wallFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
ElementClassFilter familyFilter = new ElementClassFilter(typeof(FamilyInstance));
ElementCategoryFilter massFilter = new ElementCategoryFilter(BuiltInCategory.OST_Mass);
IList<ElementFilter> filterList = new List<ElementFilter>();
filterList.Add(wallFilter);
filterList.Add(familyFilter);
filterList.Add(massFilter);
LogicalOrFilter filter = new LogicalOrFilter(filterList);
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), filter, Element.GetChangeTypeGeometry());
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), filter, Element.GetChangeTypeElementDeletion());
}
public Result OnShutdown(UIControlledApplication application) {return Result.Succeeded;}
}
public class SpatialFieldUpdater : IUpdater
{
AddInId addinID;
UpdaterId updaterID;
ElementId sphereID;
ElementId viewID;
public SpatialFieldUpdater(AddInId id, ElementId sphere, ElementId view)
{
addinID = id;
sphereID = sphere;
viewID = view;
updaterID = new UpdaterId(addinID, new Guid("FBF2F6B2-4C06-42d4-97C1-D1B4EB593EFF"));
}
public void Execute(UpdaterData data)
{
Document doc = data.GetDocument();
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
View view = doc.GetElement(viewID) as View;
FamilyInstance sphere = doc.GetElement(sphereID) as FamilyInstance;
LocationPoint sphereLP = sphere.Location as LocationPoint;
XYZ sphereXYZ = sphereLP.Point;
SpatialFieldManager sfm = SpatialFieldManager.GetSpatialFieldManager(view);
if (sfm == null) sfm = SpatialFieldManager.CreateSpatialFieldManager(view, 3); // Three measurement values for each point
sfm.Clear();
FilteredElementCollector collector = new FilteredElementCollector(doc,view.Id);
ElementCategoryFilter wallFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
ElementCategoryFilter massFilter = new ElementCategoryFilter(BuiltInCategory.OST_Mass);
LogicalOrFilter filter = new LogicalOrFilter(wallFilter, massFilter);
ICollection<Element> elements = collector.WherePasses(filter).WhereElementIsNotElementType().ToElements();
foreach (Face face in GetFaces(elements))
{
int idx = sfm.AddSpatialFieldPrimitive(face.Reference);
List<double> doubleList = new List<double>();
IList<UV> uvPts = new List<UV>();
IList<ValueAtPoint> valList = new List<ValueAtPoint>();
BoundingBoxUV bb = face.GetBoundingBox();
for (double u = bb.Min.U; u < bb.Max.U; u = u + (bb.Max.U - bb.Min.U) / 15)
{
for (double v = bb.Min.V; v < bb.Max.V; v = v + (bb.Max.V - bb.Min.V) / 15)
{
UV uvPnt = new UV(u, v);
uvPts.Add(uvPnt);
XYZ faceXYZ = face.Evaluate(uvPnt);
// Specify three values for each point
doubleList.Add(faceXYZ.DistanceTo(sphereXYZ));
doubleList.Add(-faceXYZ.DistanceTo(sphereXYZ));
doubleList.Add(faceXYZ.DistanceTo(sphereXYZ) * 10);
valList.Add(new ValueAtPoint(doubleList));
doubleList.Clear();
}
}
FieldDomainPointsByUV pnts = new FieldDomainPointsByUV(uvPts);
FieldValues vals = new FieldValues(valList);
AnalysisResultSchema resultSchema1 = new AnalysisResultSchema("Schema 1", "Schema 1 Description");
IList<int> registeredResults = new List<int>();
registeredResults = sfm.GetRegisteredResults();
int idx1 = 0;
if (registeredResults.Count == 0)
{
idx1 = sfm.RegisterResult(resultSchema1);
}
else
{
idx1 = registeredResults.First();
}
sfm.UpdateSpatialFieldPrimitive(idx, pnts, vals, idx1);
}
}
public string GetAdditionalInformation() { return "Calculate distance from sphere to walls and display results"; }
public ChangePriority GetChangePriority() { return ChangePriority.FloorsRoofsStructuralWalls; }
public UpdaterId GetUpdaterId() { return updaterID; }
public string GetUpdaterName() { return "Distance to Surfaces"; }
private FaceArray GetFaces(ICollection<Element> elements)
{
FaceArray faceArray = new FaceArray();
Options options = new Options();
options.ComputeReferences = true;
foreach (Element element in elements)
{
GeometryElement geomElem = element.get_Geometry(options);
if (geomElem != null)
{
foreach (GeometryObject geomObj in geomElem)
{
Solid solid = geomObj as Solid;
if (solid != null)
{
foreach (Face f in solid.Faces)
{
faceArray.Append(f);
}
}
GeometryInstance inst = geomObj as GeometryInstance;
if (inst != null) // in-place family walls
{
foreach (Object o in inst.SymbolGeometry)
{
Solid s = o as Solid;
if (s != null)
{
foreach (Face f in s.Faces)
{
faceArray.Append(f);
}
}
}
}
}
}
}
return faceArray;
}
}
}
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598