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

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

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


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

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

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

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

請注意,此三維預覽,是在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控件的界面如下:

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

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

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

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

六、看下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自定義控件的方法定義

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

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


分享到:


相關文章: