MultithreadedCalculation--Revit多线程计算
Revit多线程计算——Advanced
A combination of Analysis Visualization Framework, multi-threading, Revit’s Idling event, and Dynamic Model Update to simulate how analysis results can be periodically updated during computation and re-started when the Revit model changes.
分析可视化,多线程,Revit空闲事件得大综合,用动态模型更新来模拟当模型修改时,分析结果是如何在计算和重启之间阶段性得更新。
效果图:
动态模型更新(DMU: Dynamic Model Update)
The interface used to create an updater capable of reacting to changes in the Revit model.
这个接口可以用于创建一个订阅Revit模型改变而反应的更新器
public interface IUpdater
{
void Execute(UpdaterData data);
string GetAdditionalInformation();
ChangePriority GetChangePriority();
UpdaterId GetUpdaterId();
string GetUpdaterName();
}
// Register updater to watch for geometry changes
SpatialFieldUpdater updater = new SpatialFieldUpdater(container,uiApp.ActiveAddInId);
if (!UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId()))
// 向文档中注册一个更新对象
UpdaterRegistry.RegisterUpdater(updater, doc);
// 检测的id集合
IList<ElementId> idCollection = new List<ElementId>();
idCollection.Add(element.Id);
UpdaterRegistry.RemoveAllTriggers(s_updaterId);
// 添加一个监听行为,主要对添加的元素进行监听
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), doc, idCollection, Element.GetChangeTypeGeometry());
监听行为的重载
AddTrigger(UpdaterId, ElementFilter, ChangeType) // 对过滤的对象进行监听
AddTrigger(UpdaterId, Document, ElementFilter, ChangeType) // 对指定文档的过滤元素进行监听
AddTrigger(UpdaterId, Document, ICollection<(Of <<(ElementId>)>>), ChangeType) // 对指定文档,指定集合的元素进行监听
代码核心逻辑
// Register idling event
uiApp.Idling += new EventHandler<IdlingEventArgs>(container.UpdateWhileIdling);
// Start new thread
Thread thread = new Thread(new ThreadStart(container.Run));
thread.Start();
核心类
public class MultithreadedCalculationContainer
{
private volatile bool m_stop = false;
...
// lock互斥锁对象
IList<ResultsData> results = new List<ResultsData>();
// start函数
public void Run()
{
m_uvToCalculate = DetermineFacePoints();
m_uvToCalculateCount = m_uvToCalculate.Count;
Calculate();
}
/// <summary>
/// Stops the thread/calculation and application via idling.
/// </summary>
public void Stop()
{
m_stop = true;
}
/// <summary>
/// The idling callback which adds data to the AVF results.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// 注册的事件
public void UpdateWhileIdling(object sender, IdlingEventArgs e)
{
...
// If stopping, clear results and unset event.
if (m_stop)
{
lock (results)
{
results.Clear();
}
uiApp.Idling -= UpdateWhileIdling;
return;
}
// If document was closed and new document opened, do not run the update.
if (uiApp.ActiveUIDocument.Document.PathName == m_docName)
{
// Lock access to current calculated results
lock (results)
{
if (results.Count == 0) return;
// Turn each result to an AVF ValueAtPoint
...
if (!m_stop)
sfm.UpdateSpatialFieldPrimitive(s_spatialFieldId, pntsByUV, fieldValues, schemaIndex);
t.Commit();
// Clear results already processed.
results.Clear();
// If no more results to process, remove the idling event
if (m_uvToCalculateCount == 0)
{
uiApp.Idling -= UpdateWhileIdling;
s_oldViewId = s_activeViewId;
s_oldSpatialFieldId = s_spatialFieldId;
}
}
}
}
// Calculate the results in a loop
void Calculate()
{
....
// Lock access to results while the data is added
lock (results)
{
results.Add(new ResultsData(uv, 1000 * Math.Sin(Math.Abs(uv.U * uv.V))));
Thread.Sleep(500); // to simulate the effect of a complex computation
m_uvToCalculateCount--;
}
....
}
}
BIM树洞
做一个静谧的树洞君
用建筑的语言描述IT事物;
用IT的思维解决建筑问题;
共建BIM桥梁,聚合团队。
本学习分享资料不得用于商业用途,仅做学习交流!!如有侵权立即删除!!
-
微信公众号: BIM树洞
-
知乎专栏:BIM树洞
-
气氛组博客:http://www.31bim.com
-
BIM应用及咨询,CAD,Revit, OpenGL,图形开发交流,加Q群1083064224