C# Revit二次开发基础/核心编程--- Application\Document\Transaction
Application\Document\Transaction 和其例子
Revit和Mcirosoft Office一样,使用多文档模型,在Revit API的类结构中,应用类和文档类处于最顶层的。他们分为Application、UIApplication、Document、UIDocument这几大类。
1) Autodesk.Revit.UI.UIApplication:提供访问UI级别接口的应用类,包括访问用户界面RibbonPanels、获得用户界面活动文档等能力。
2)Autodesk.Revit.ApplicationServices.Application:提供了访问其他应用级别内容接口的应用类。
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { Autodesk.Revit.UI.UIApplication uiApp = revit.Application; Autodesk.Revit.ApplicationServices.Application app = uiApp.Application; Autodesk.Revit.UI.UIDocument uiDoc = uiApp.ActiveUIDocument; Autodesk.Revit.DB.Document doc = uiDoc.Document; |
3) Revit版本及产品信息:Revit的Application对象包括了以下的Revit版本及产品信息,他们可以为插件提供Revit的发布信息。
public string VersionBuild { get; }
public string VersionName { get; }
public string VersionNumber { get; }
public string SubVersionNumber { get; }
public ProductType Product { get; }
public LanguageType Language { get; }
public void GetVersionInfo(Autodesk.Revit.ApplicationServices.Application app) { if(app.VersionNumber=="2018") { TaskDialog.Show("Supported Version", "2018 OK"); } else { TaskDialog dialog = new TaskDialog("Unsupported version."); dialog.MainIcon = TaskDialogIcon.TaskDialogIconWarning; dialog.MainInstruction = "This application is only supported in revit 2018"; dialog.Show(); } } |
4) 共享参数管理:Revit提供了共享参数机制,Application类中的OpenSharedParameterFile()方法可以用来访问共享参数文件。Application类中的SharedParametersFilename属性提供了共享参数文件的名称。
5)插件管理:UIApplication类提供的ActiveAddInId用来获取当前活跃的外部应用或者外部命令的ID。同时UIApplication类也提供了LoadedApplications属性来返回一个成功加载插件的列表。
6)UI扩展:UIApplication提供了创建自定义Ribbon面板和控件的方法。
Autodesk.Revit.UI.UIDocument:提供访问UI级别接口的文档类,比如提供Selection来表示用户界面的选择集。
Autodesk.Revit.DB.Document:提供访问其他文档基本内容的文档类。
2)位置和场地:SiteLocation
public class SiteLocation : ElementType { public double Elevation { get; } public string GeoCoordinateSystemDefinition { get; } public string GeoCoordinateSystemId { get; } public double Latitude { get; set; } public double Longitude { get; set; } public string PlaceName { get; set; } public double TimeZone { get; set; } public string WeatherStationName { get; } public DateTime ConvertFromProjectTime(DateTime projectTime); public DateTime ConvertToProjectTime(DateTime inputTime); public bool IsCompatibleWith(SiteLocation otherSiteLocation); } |
Document类的 public ProjectLocationSet ProjectLocations { get; }
3)视图管理:doc.ActiveView
4)获取元素:通过ElementId获取元素;通过引用获取元素;通过UniqueId获取元素。
5)UIDcoument包含了跟UI相关的文档信息和操作,比如ActiveView和ShowElement。
app.Documents;
doc.PathName;
doc.Title;
app.NewFamilyDocument;
app.NewProjectDocument;
app.NewProjectTemplateDocument;
app.OpenDocumentFile(string fileName);
app.OpenDocumentFile(modelPath, openOptions);
Document :
public void Save();
public void Save(SaveOptions options);
public void SaveAs(string filepath);
public void SaveAs(ModelPath path, SaveAsOptions options);
public void SaveAs(string filepath, SaveAsOptions options);
public bool Close();
public bool Close(bool saveModified);
UIDocument:
public bool SaveAndClose();
public void SaveAs();
public void SaveAs(UISaveAsOptions options);
(5)类别Category:
Categories:Model Categories 梁、柱、门、窗、墙等;
Annotation Categories:尺寸、网格、标高、文本标注等。
遵循的原则:
-| 基本原则:每个族对象属于一个类别;非族对象,比如材质、视图等不属于任何类别。
-| ProjectInfo类是个例外,它属于Project Information类别。
-| 一个元素和它的类型通常都属于同一个类别。
-|同一元素类型可以属于不同的类别。
-|不同元素可以属于同一类别。
Document : public Settings Settings { get; }
//
// 摘要:
// The settings object provides access to general components of the Autodesk Revit
// application, such as Categories.
public class Settings : APIObject
{
public Categories Categories { get; }
public ElectricalSetting ElectricalSetting { get; }
public TilePatterns TilePatterns { get; }
}
Category的用途:
-|可以作为元素分类的方法
-|元素根据类别不同,参数也不同。
-|类别也可以用来控制可见性和图形外观。
Category Id:
(6)打印。
事务是将一系列修改Revit模型的操作提交至文档的这样一种对象。任何一个对文档修改的操作都需要包含在一个打开的属于该文档的事务中,否则就会有异常抛出。任何修改都需要事务提交后才写入文档。在一个事务中进行的所有修改都能被撤销。在任何时候,一个文档当前只能有一个打开的事务,但在一个事务中可以有一个或多个修改模型的操作。
和事务有关的三个类:
Transaction
SubTransaction
TransactionGroup
事务只能从API支持的环境中启动,如外部命令、事件等。
public TransactionStatus Start() public TransactionStatus Commit(); public TransactionStatus RollBack(); public TransactionStatus GetStatus(); public enum TransactionStatus { // // 摘要: // initial value, the transaction has not been started yet in this status Uninitialized = 0, // // 摘要: // transaction has begun (until committed or rolled back) Started = 1, // // 摘要: // rolled back (aborted) RolledBack = 2, // // 摘要: // simply committed, ended an empty transaction, flushed all, or undo is disabled Committed = 3, // // 摘要: // returned from error handling that took over managing the transaction Pending = 4, // // 摘要: // error while committing or rolling back Error = 5, // // 摘要: // while still in error handling (internal status) Proceed = 6 } |
要修改Revit中的文档中的模型就需要一个Transaction。在同一时间内,只有一个Transaction可以被打开,不允许嵌套。每个Transaction需要一个名字,当这个Transaction被成功提交后,这个名字会被显示在Undo菜单中。
一个SubTransaction可以用来提交一组操作。子事务是可选的。用来将一些复杂的任务分解成许多小任务来提交。SubTransaction必须在一个打开的Transaction中创建,在Transaction关闭(提交或撤销)前关闭(提交或撤销)。与事务不同的是,子事务可以嵌套,但嵌套内的子事务必须在嵌套外的子事务关闭前关闭。子事务没有名字,因为它不会显示在Undo菜单中。
TransactionGroup用来将几个独立的事务分组,这样一个组可以同时处理许多事务。当一个TransactionGroup撤销时,所有的在这个组里面的事务,哪怕已经提交的,都会被撤销。如果一个TransactionGroup被提交,这个组里的事务保持原来状态(提交或撤销)。如果一个TransactionGroup被吸收(Assimilate),那么这个组里的所有事务将被合并成一个成功提交的事务。并使用这个组的名字显示在Undo菜单中。
在事件中使用事务:
在事件中修改文档
事务调用触发的事件
//1 这是先选择元素后执行命令 public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { try { //在执行插件前,先选择一些元素。//取到当前文档 UIDocument uidoc = revit.Application.ActiveUIDocument;
Selection selection = uidoc.Selection; ICollection<ElementId> collection = selection.GetElementIds(); if (collection.Count == 0) { TaskDialog.Show("Revit", "你没有选择任何元素"); } else { string info = "所选元素类型是:"; foreach (ElementId elemId in collection) { Element elem = revit.Application.ActiveUIDocument.Document.GetElement(elemId); info += "\n\t" + elem.GetType().ToString(); } TaskDialog.Show("Revit", info); } } catch (Exception e) { message = e.Message; return Autodesk.Revit.UI.Result.Failed; } return Autodesk.Revit.UI.Result.Succeeded; } |
//在运行外部命令过程中选取元素 public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { try { Document document = revit.Application.ActiveUIDocument.Document; //点选指定类型的元素。本例中指定的类型为元素整体。 Reference pickedElemRef = revit.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element); //通过引用渠道选中的元素 Element elem = document.GetElement(pickedElemRef.ElementId); string info = "所选元素类型为:"; info += "\n\t" = elem.GetType().ToString(); TaskDialog.Show("Revit", info); } catch (Exception e) { message = e.Message; return Autodesk.Revit.UI.Result.Failed; } return Autodesk.Revit.UI.Result.Succeeded; } |
//通过过滤器取到元素 public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { try { Document document = revit.Application.ActiveUIDocument.Document; //创建一个类过滤器来过滤所有的FamilyInstance类的元素 ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance)); //创建一个类别过滤器来过滤出所有的内建类型为OST_Door的元素 ElementCategoryFilter doorsCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors); //创建一个逻辑过滤器来组合前面两个过滤器,实现过滤出所有的Door元素 LogicalAndFilter doorInstanceFilter = new LogicalAndFilter(familyInstanceFilter, doorsCategoryFilter); FilteredElementCollector collector = new FilteredElementCollector(document); ICollection<ElementId> doors = collector.WherePasses(doorInstanceFilter).ToElementIds(); string prompt = "The ids of the doors in the current document are:"; foreach(ElementId id in doors) { prompt += "\n\t" + id.IntegerValue; } TaskDialog.Show("Revit",prompt); } catch(Exception e) { message = e.Message; return Autodesk.Revit.UI.Result.Failed; } return Autodesk.Revit.UI.Result.Succeeded; } |
1、应用类和文档类:UIApplication、Application、UIDocument、Document类
2、事务相关的三个类:Transaction、SubTransaction、TransactionGroup类
3、有三个例子。//通过过滤器取到元素,课后自己敲一敲代码。