Revit二次開發,在winform中製作3d預覽效果

目前,見到使用的三維預覽,是以二維平面生成的線段,類似如:


那麼如何做到真正的三維效果呢?我們知道,要在winform中生成三維,那一般得需要有3d引擎。但我們不太可能為了某一個功能,跑去開發一個3d引擎,如果真能開發出3d引擎,那麼你自己就可以開一家公司了,光3d引擎技術就夠你吃香的喝辣的了。

言歸正傳,本文是使用Revit的三維效果,嵌入到winfrom中實現的。

正文開始之前,先看下最終效果:

請注意,此三維預覽,是在winform中先預覽,然後才去Revit中,生成你的實際效果。而不是將Revit的建築預覽到Winform中。

一、首先我們先實現IExternalCommand接口,製作一個插件

<code>using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using Previewer; using Previewer.Extensions; using Previewer.Runtime; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Windows.Forms; namespace Rotation { /// /// Revit預覽 /// /// marc [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)] public class DefaultCommand : IExternalCommand { /// /// 執行指令 /// /// /// /// /// public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var activeDocument = commandData.Application.ActiveUIDocument; var document = activeDocument.Document; IDataContext context = new DataContext(commandData); RevitRuntime.SetDataContext(context); Result result; Transaction tran = new Transaction(document, Guid.NewGuid().ToString()); try { tran.Start(); IWork work = new PreviewWork(); result = work.Run(); tran.Commit(); } catch (System.Exception exp) { tran.RollBack(); result = Result.Failed; Debug.WriteLine(exp.Message); } finally { tran.Dispose(); } return result; } } } /<code>

上述接口實現,裡面就一句核心代碼:IWork.Run(),也就是說業務邏輯的代碼,已經放在了Run方法中,那麼我們看下IWork接口

二、定義IWork業務邏輯接口

<code>using Autodesk.Revit.UI; namespace Previewer { /// /// 邏輯作業接口 /// /// marc public interface IWork { /// /// 運行 /// /// Result Run(); } }/<code>

三、實現IWork方法

<code>using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Previewer.UI; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Previewer { /// /// Revit預覽的具體邏輯 /// /// marc public class PreviewWork : IWork { /// /// 運行 /// /// public virtual Result Run() { this.ShowForm(); return Result.Succeeded; } /// /// 顯示窗體 /// private void ShowForm() { var document = PreviewConfigure.GetOrCreateDocument(PreviewRealtime.ProjectName); using (Transaction tran = new Transaction(document, Guid.NewGuid().ToString())) { tran.Start(); var form = new PreviewForm(); DialogResult result = form.ShowDialog(); if (result != DialogResult.OK) { tran.RollBack(); return; } tran.Commit(); } } } } /<code>

如上述,我們的具體實現,只是顯示了一個Winform窗體。

四、我們在顯示Winform窗體之前,先創建一個自定義的Winform控件

自定義Winform控件的界面如下:

五、下面創建一個Winform窗體,並載入上面的自定義控件,界面如下:

右側看不見的區域,就是自定義控件的東西。用來顯示三維預覽的。

六、看下Winform窗體的代碼,講解下:

<code>using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using Previewer.Core; using Previewer.CustomControls; using Previewer.Runtime; using Previewer.UI; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Previewer { /// /// 預覽窗體 /// /// marc public partial class PreviewForm : FormBase { /// /// 實時預覽對象 /// private readonly IPreviewRealtime _previewRealtime; private Preview _preview; /// /// 構造函數 /// public PreviewForm() { InitializeComponent(); this._previewRealtime = new PreviewRealtime(); this.LoadPreviewControl(); } /// /// 加載預覽控件 /// private void LoadPreviewControl() { this._preview = new Preview { Dock = DockStyle.Fill, Location = new System.Drawing.Point(0, 0), Name = "Preview", TabIndex = 0, Text = "預覽", IsVisibleDocuments = false, IsVisibleDropdownList = true }; this.PreviewPanel.Controls.Add(_preview); _preview.SetDefaultDocument(this._previewRealtime.Document); } /// /// 預覽效果 /// /// /// private void PreviewButton_Click(object sender, EventArgs e) { this._preview.Clear(); this._previewRealtime.Build(); this.TipLabel1.Visible = true; this.TipLabel2.Visible = true; this.TipLabel3.Visible = true; this.TipLabel4.Visible = true; this.CreateButton.Visible = true; } /// /// 真正的在Revit中生成想要的圖元,效果等於你在預覽圖中看到的一樣 /// /// /// private void CreateButton_Click(object sender, EventArgs e) { var document = RevitRuntime.DataContext.Document; IDraw draw = new Draw(); draw.Demo(document); this.DialogResult = DialogResult.OK; this.Close(); } /// /// 當窗體關閉時發生 /// /// /// private void PreviewForm_FormClosed(object sender, FormClosedEventArgs e) { this._preview.Clear(); } } } /<code>

我們使用LoadPreviewControl()方法加載了三維預覽控件,初始化了Preview對象,Preview對象是自定義的Winform控件。

預覽方法PreviewButton_Click()是一個點擊事件,點擊後,將出現預覽效果。他的核心是調用了this._previewRealtime.Build();

預覽效果滿意後,可以使用CreateButton_Click()進行確定,並自動關閉窗體,然後在Revit中生成剛剛預覽的效果。

由於之前預覽時生成的預覽效果,將以族實例的方式存儲在Revit中,所以,我們在關閉窗體,或者多次預覽時,都需要調用一下清除方法:this._preview.Clear();

七、看一下Preview自定義控件的方法定義

IsVisibleDocuments:是否顯示文檔選擇列表

IsVisibleDropdownList:是否顯示下拉列表

Clear:清空當前Document文檔已經生成的預覽對象

SetDefaultDocument:設置默認操作文檔

SetDefaultView:設置默認視圖,不設的話,我們默認為3d


八、生成預覽的接口定義

<code>using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Previewer.UI { /// /// 實時預覽接口 /// /// marc public interface IPreviewRealtime { /// /// 預覽所用的文檔對象 /// Document Document { get; } /// /// 創建 /// void Build(); } } /<code>

該接口定義了一個屬性Document,代表將在哪個Document中生成預覽效果。

還定義了一個Build()方法,調用該方法後,將即時在此Document中生成預覽效果。

九、繪製圖像。也就是建築了。

<code>using Autodesk.Revit.DB; namespace Previewer.Core { /// /// 繪製 /// /// marc public interface IDraw { /// /// 製作一個demo /// /// 操作文檔 void Demo(Document document); } }/<code>

由於我們只是為了Demo,所以繪製方法裡,就只寫了一個生成Demo的方法。實際生產中,可以自行更換為您自己需要的方法。


最後,你就可以生成這個dll,加載到Revit中進行實際測試了。文章最後附上了完整源碼,並帶有完整註釋。祝您用餐愉快。


源碼下載:https://download.csdn.net/download/mazhiyuan1981/12915401