EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 833|回复: 3
打印 上一主题 下一主题

Revit里模型动态更新DMU的用法

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12404

社区QQ达人

跳转到指定楼层
楼主
发表于 2014-1-15 14:05:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
许多时候,开发者希望Revit有这样的功能。当用户对模型进行修改后,二次开发的程序能够相应用户的修改,对模型作出一些相应的修改操作。例如,一些墙上的窗户要求永远居中显示。当用户对这个墙做了长度修改,这个窗户还要自动的在墙的中心处。这就是一个比较容易理解的应用。
这要求Revit具有感知用户所做的操作,并且能随后对模型作出修改。对于感知用户的操作或动作,Revit有两个办法,一个是用反应器,也就是事件。另一个是模型动态更新机制DMU(Dynamic Model Update)。


Revit提供了一些事件,比如捕获文档的打开,保存,关闭,打印,视图切换等等。也提供了构建级别的事件(DocumentChanged)来捕获有新的对象加入,或有些对象发生修改,或一些对象的参数发生变化。但是在DocumentChanged事件处理函数里,无法对模型进行修改。禁止在这里进行模型的修改是为了防止循环调用DocumentChanged事件处理函数,形成死循环。基于这个原因,Revit 提供了DMU机制,模型动态更新。


DMU具有感知用户对模型进行了构建级别的修改,并且可以进行作出相应。而且在这里可以对模型进行修改。它之所以无法触发循环调用,是因为它对模型所做的修改和用户模型所做的修改共享同一个事务。在代码中对模型进行修改后,程序员无法掌控什么时候提交修改事务,Revit系统自动来提交事务的修改。


下面代码是DMU的一个例子,让窗户永居中的代码。


用法:


首先加载和注册DMU:


  1. [csharp] view plaincopy
  2. [Transaction(TransactionMode.Automatic)]  
  3. public class UIEventApp : IExternalApplication  
  4. {  
  5.   // Flag to indicate if we want to show a message at each object modified events.   
  6.   public static bool m_showEvent = false;  
  7.   
  8.   /// <summary>  
  9.   /// OnShutdown() - called when Revit ends.   
  10.   /// </summary>  
  11.   public Result OnShutdown(UIControlledApplication app)  
  12.   {  
  13.     // (1) unregister our document changed event hander   
  14.     app.ControlledApplication.DocumentChanged -= UILabs_DocumentChanged;  
  15.   
  16.     return Result.Succeeded;  
  17.   }  
  18.   
  19.   /// <summary>  
  20.   /// OnStartup() - called when Revit starts.   
  21.   /// </summary>  
  22.   public Result OnStartup(UIControlledApplication app)  
  23.   {  
  24.   
  25.     // (2) register our dynamic model updater (WindowDoorUpdater class definition below.)   
  26.     // We are going to keep doors and windows at the center of the wall.   
  27.     //   
  28.     // Construct our updater.   
  29.     WindowDoorUpdater winDoorUpdater = new WindowDoorUpdater(app.ActiveAddInId);  
  30.     // ActiveAddInId is from addin menifest.   
  31.     // Register it   
  32.     UpdaterRegistry.RegisterUpdater(winDoorUpdater);  
  33.   
  34.     // Tell which elements we are interested in being notified about.   
  35.     // We want to know when wall changes its length.   
  36.   
  37.     ElementClassFilter wallFilter = new ElementClassFilter(typeof(Wall));  
  38.     UpdaterRegistry.AddTrigger(winDoorUpdater.GetUpdaterId(), wallFilter, Element.GetChangeTypeGeometry());  
  39.   
  40.     return Result.Succeeded;  
  41.   }  
  42. [csharp] view plaincopy
  43. //。。。  
  44. [csharp] view plaincopy
  45. }  
复制代码


模型动态更新的实现类。在这里实现了如何更新模型。

[csharp] view plaincopy//========================================================    // dynamic model update - derive from IUpdater class    //========================================================      public class WindowDoorUpdater : IUpdater   {     // Unique id for this updater = addin GUID + GUID for this specific updater.      UpdaterId m_updaterId = null;       // Flag to indicate if we want to perform      public static bool m_updateActive = false;       /// <summary>     /// Constructor      /// </summary>     public WindowDoorUpdater(AddInId id)     {       m_updaterId = new UpdaterId(id, new Guid("EF43510F-38CB-4980-844C-72174A674D56"));     }       /// <summary>     /// This is the main function to do the actual job.      /// For this exercise, we assume that we want to keep the door and window always at the center.      /// </summary>     public void Execute(UpdaterData data)     {       if (!m_updateActive) return;         Document rvtDoc = data.GetDocument();       ICollection<ElementId> idsModified = data.GetModifiedElementIds();         foreach (ElementId id in idsModified)       {         //  Wall aWall = rvtDoc.get_Element(id) as Wall; // For 2012         Wall aWall = rvtDoc.GetElement(id) as Wall; // For 2013         CenterWindowDoor(rvtDoc, aWall);           //Get the wall solid.            Options opt = new Options();         opt.ComputeReferences = false;           Solid wallSolid = null;         GeometryElement geoElem = aWall.get_Geometry(opt);         foreach (GeometryObject geoObj in geoElem.Objects)         {           wallSolid = geoObj as Solid;           if (wallSolid != null)           {             if (wallSolid.Faces.Size > 0)             {               break;             }           }         }         //XYZ ptCenter = wallSolid.ComputeCentroid();               }     }  

下面这个函数是窗居中操作。
  1. [csharp] view plaincopy
  2. /// <summary>  
  3.     /// Helper function for Execute.   
  4.     /// Checks if there is a door or a window on the given wall.   
  5.     /// If it does, adjust the location to the center of the wall.   
  6.     /// For simplicity, we assume there is only one door or window.   
  7.     /// (TBD: or evenly if there are more than one.)   
  8.     /// </summary>  
  9.     public void CenterWindowDoor(Document rvtDoc, Wall aWall)  
  10.     {  
  11.       // Find a winow or a door on the wall.   
  12.       FamilyInstance e = FindWindowDoorOnWall(rvtDoc, aWall);  
  13.       if (e == null) return;  
  14.   
  15.       // Move the element (door or window) to the center of the wall.   
  16.   
  17.       // Center of the wall   
  18.       LocationCurve wallLocationCurve = aWall.Location as LocationCurve;  
  19.       XYZ pt1 = wallLocationCurve.Curve.get_EndPoint(0);  
  20.       XYZ pt2 = wallLocationCurve.Curve.get_EndPoint(1);  
  21.       XYZ midPt = (pt1 + pt2) * 0.5;  
  22.   
  23.       LocationPoint loc = e.Location as LocationPoint;  
  24.       loc.Point = new XYZ(midPt.X, midPt.Y, loc.Point.Z);  
  25.     }  
  26.   
  27.     /// <summary>  
  28.     /// Helper function   
  29.     /// Find a door or window on the given wall.   
  30.     /// If it does, return it.   
  31.     /// </summary>  
  32.     public FamilyInstance FindWindowDoorOnWall(Document rvtDoc, Wall aWall)  
  33.     {  
  34.       // Collect the list of windows and doors   
  35.       // No object relation graph. So going hard way.   
  36.       // List all the door instances   
  37.       var windowDoorCollector = new FilteredElementCollector(rvtDoc);  
  38.       windowDoorCollector.OfClass(typeof(FamilyInstance));  
  39.   
  40.       ElementCategoryFilter windowFilter = new ElementCategoryFilter(BuiltInCategory.OST_Windows);  
  41.       ElementCategoryFilter doorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);  
  42.       LogicalOrFilter windowDoorFilter = new LogicalOrFilter(windowFilter, doorFilter);  
  43.   
  44.       windowDoorCollector.WherePasses(windowDoorFilter);  
  45.       IList<Element> windowDoorList = windowDoorCollector.ToElements();  
  46.   
  47.       // This is really bad in a large model!  
  48.       // You might have ten thousand doors and windows.  
  49.       // It would make sense to add a bounding box containment or intersection filter as well.  
  50.   
  51.       // Check to see if the door or window is on the wall we got.   
  52.       foreach (FamilyInstance e in windowDoorList)  
  53.       {  
  54.         if (e.Host.Id.Equals(aWall.Id))  
  55.         {  
  56.           return e;  
  57.         }  
  58.       }  
  59.   
  60.       // If you come here, you did not find window or door on the given wall.   
  61.   
  62.       return null;  
  63.     }  
复制代码

在Revit有三个例子演示了DMU的使用机制。请搜索UpdaterRegistry.RegisterUpdater 找到这几个例子更多了解模型动态更新的用法。转载请复制以下信息:原文链接: http://blog.csdn.net/joexiongjin/article/details/84855681作者:  叶雄进 , Autodesk ADN


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对

相关帖子

工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言

12

主题

899

帖子

1638

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1638
2F
发表于 2014-2-13 10:20:12 | 只看该作者
本帖最后由 Aaronyee 于 2015-11-2 19:43 编辑

呵呵 皇_冠现_金网:hg88094.com首存送58元.手机可投だ注任何游戏满1000送1088彩_金だ体育半场结算六_合48倍だ各种彩票游戏

12

主题

876

帖子

1510

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1510
3F
发表于 2014-2-14 10:14:36 | 只看该作者
本帖最后由 Aaronyee 于 2015-11-2 19:43 编辑

顶!!!!!!!!!! 皇_冠现_金网:hg88094.com首存送58元.手机可投℃注任何游戏满1000送1088彩_金℃体育半场结算六_合48倍℃各种彩票游戏

12

主题

992

帖子

1806

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1806
4F
发表于 2014-2-20 14:07:39 | 只看该作者
本帖最后由 Aaronyee 于 2015-11-2 19:43 编辑

路过!!! 不发表意见…… SO娱乐城:真_人.足球.彩票齐全| 开户送10元.首存送58元.手机可投,注任何游戏顶级信用,提现即时到账SO.CC
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|EaBIM网 ( 苏ICP备2020058923号-1  苏公网安备32011502011255号

GMT+8, 2024-11-16 17:10

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表