• xBIM 实战04 在WinForm窗体中实现IFC模型的加载与浏览


      WPF底层使用 DirectX 进行图形渲染。DirectX  能理解可由显卡直接渲染的高层元素,如纹理和渐变,所以 DirectX 效率更高。而 GDI/GDI+不理解这些高层元素,因此必须将他们转换成逐像素指令,而通过现代显卡渲染这些指令更慢。WinForm 的绘图技术使用的就是GDI/GDI+技术。但是xBIM并没有提供专门针对传统 WinForm 技术的的模型查看器。如果确实需要在传统的 WinForm 窗体中也要加载并显示BIM(.ifc格式)模型文件该如何处理呢?

      由于WinForm与WPF技术可以互通互用,所以本文介绍一种取巧的方式,在WinForm窗体中加载WPF控件,WPF控件中渲染BIM(.ifc格式)模型文件。具体操作步骤如下详细介绍。

    一、新建WinForm项目
       新建WinForm项目,.NET Framework 选择4.7版本,因为需要引用最新的 XBIM相关DLL(依赖 .NET Framework 4.7)。 
    二、添加xBIM相关DLL引用
      通过NuGet程序包管理器添加xBIM相关的DLL引用
     需要应用下列DLL
    三、添加WPF相关DLL引用
      通过NuGet程序包管理器添加WPF相关的DLL引用。其中 HelixToolkit 是开发wpf3D应用的开源库,比较好用。

    添加引用后,自动添加了下列WPF的基础库。

    四、在Winform项目中添加WPF用户控件

    编写XAML代码如下:

     1 <UserControl x:Class="Xbim.WinformsSample.WinformsAccessibleControl"
     2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     6              xmlns:presentation="http://schemas.Xbim.com/Presentation"
     7              mc:Ignorable="d" 
     8              d:DesignHeight="600" d:DesignWidth="800"
     9              x:Name="MainWindow"
    10              DataContext="{Binding RelativeSource={RelativeSource Self}}">
    11     <Grid Name="MainFrame">
    12         <presentation:DrawingControl3D x:Name="DrawingControl" 
    13                                        x:FieldModifier="public"  
    14                                        Model ="{Binding ModelProvider.ObjectInstance}" 
    15                                        Focusable="True" 
    16                                        Width="Auto" 
    17                                        Height="Auto"
    18                                        SelectedEntityChanged="DrawingControl_SelectedEntityChanged"
    19                                        ModelOpacity="1">
    20         </presentation:DrawingControl3D>
    21     </Grid>
    22 </UserControl>

    其中第12行,引用了 xBIM官方提供的 模型浏览器组件。显示效果如下:

    五、在WinForm窗体中调用WPF查看器

      添加一个WinForm窗体。左侧Panel中是 按钮区域,右侧Panel填充窗体剩余的所有区域。

     
    打开VS的工具箱,可以看到如下栏目
     
    WPF互操作性,将 “ElementHost”控件拖拽到右侧Panel中,命名为controlHost,并设置 Dock 属性为 Fill。

     后台逻辑:在第四步骤中创建了一个WPF用户控件,在此处实例化一个对象

    private WinformsAccessibleControl _wpfControl;

    在构造函数中初始化该对象并将对象添加到 controlHost 中

     1  public FormExample(ILogger logger = null)
     2         {
     3             InitializeComponent();
     4 
     5             Logger = logger ?? new LoggerFactory().CreateLogger<FormExample>();
     6             
     7             IfcStore.ModelProviderFactory.UseHeuristicModelProvider();
     8 
     9             _wpfControl = new WinformsAccessibleControl();
    10             _wpfControl.SelectionChanged += _wpfControl_SelectionChanged;
    11 
    12             controlHost.Child = _wpfControl;
    13         }

    运行效果如下:

    完整的示例代码如下:

      1 using System;
      2 using System.Linq;
      3 using System.Windows.Forms;
      4 
      5 using Microsoft.Extensions.Logging;
      6 
      7 using Xbim.Common;
      8 using Xbim.Ifc;
      9 using Xbim.Ifc4.Interfaces;
     10 using Xbim.ModelGeometry.Scene;
     11 
     12 namespace Xbim.WinformsSample
     13 {
     14     public partial class FormExample : Form
     15     {
     16         private WinformsAccessibleControl _wpfControl;
     17 
     18         int starting = -1;
     19 
     20         protected ILogger Logger { get; private set; }
     21 
     22         public FormExample(ILogger logger = null)
     23         {
     24             InitializeComponent();
     25 
     26             Logger = logger ?? new LoggerFactory().CreateLogger<FormExample>();
     27             
     28             IfcStore.ModelProviderFactory.UseHeuristicModelProvider();
     29 
     30             _wpfControl = new WinformsAccessibleControl();
     31             _wpfControl.SelectionChanged += _wpfControl_SelectionChanged;
     32 
     33             controlHost.Child = _wpfControl;
     34         }
     35 
     36         private void _wpfControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
     37         {
     38             var ent = e.AddedItems[0] as IPersistEntity;
     39             txtEntityLabel.Text = ent == null ? "" : ent.EntityLabel.ToString();
     40         }
     41 
     42         /// <summary>
     43         /// 打开BIM(.ifc格式)文件
     44         /// </summary>
     45         /// <param name="sender"></param>
     46         /// <param name="e"></param>
     47         private void BtnLoadBimFile_Click(object sender, EventArgs e)
     48         {
     49             var dlg = new OpenFileDialog();
     50             dlg.Filter = @"IFC Files|*.ifc;*.ifczip;*.ifcxml|Xbim Files|*.xbim";
     51             dlg.FileOk += (s, args) =>
     52                           {
     53                               LoadXbimFile(dlg.FileName);
     54                           };
     55             dlg.ShowDialog(this);
     56         }
     57 
     58         /// <summary>
     59         ///  查看模型实体标签
     60         /// </summary>
     61         /// <param name="sender"></param>
     62         /// <param name="e"></param>
     63         private void BtnNext_Click(object sender, EventArgs e)
     64         {
     65             var mod = _wpfControl.ModelProvider.ObjectInstance as IfcStore;
     66             if (mod == null)
     67                 return;
     68 
     69             var found = mod.Instances.OfType<IIfcProduct>().FirstOrDefault(x => x.EntityLabel > starting);
     70             _wpfControl.SelectedElement = found;
     71 
     72             if(found != null)
     73             {
     74                 starting = found.EntityLabel;
     75             }
     76             else
     77             {
     78                 starting = -1;
     79             }
     80         }
     81 
     82         /// <summary>
     83         ///  加载BIM(.ifc格式)文件
     84         /// </summary>
     85         /// <param name="dlgFileName"></param>
     86         private void LoadXbimFile(string dlgFileName)
     87         {
     88             // TODO: should do the load on a worker thread so as not to lock the UI. 
     89             //  如果加载的模型文件较大,耗时可能较长,建议使用后要程序处理,给用户一个好的使用体验。
     90 
     91             Clear();
     92 
     93             var model = IfcStore.Open(dlgFileName);
     94             if (model.GeometryStore.IsEmpty)
     95             {
     96                 // 使用 xBIM 几何引擎创建 GeometryEngine 对象
     97                 try
     98                 {
     99                     var context = new Xbim3DModelContext(model);
    100 
    101                     context.CreateContext();
    102 
    103                     // TODO: SaveAs(xbimFile); // so we don't re-process every time
    104                 }
    105                 catch (Exception geomEx)
    106                 {
    107                     Logger.LogError(0, geomEx, "Failed to create geometry for {filename}", dlgFileName);
    108                 }
    109             }
    110             _wpfControl.ModelProvider.ObjectInstance = model;
    111         }
    112 
    113         public void Clear()
    114         {
    115             if (_wpfControl.ModelProvider != null)
    116             {
    117                 var currentIfcStore = _wpfControl.ModelProvider.ObjectInstance as IfcStore;
    118                 currentIfcStore?.Dispose();
    119 
    120                 _wpfControl.ModelProvider.ObjectInstance = null;
    121             }
    122         }
    123     }
    124 }
     
  • 相关阅读:
    直接报错了:无法加载文件 C:UsersAdministratorAppDataRoaming pmvue.ps1,因为在此系统中禁止执行脚本
    [vue系列]-vue+vue-i18n+elementUI 国际化
    new vue 实例发生了什么呢?
    vue引用外部JS的两种方案
    web轻量级富文本框编辑
    Cannot read property '_withTask' of undefined
    element 动态合并表格
    前端如何获取原始图片大小
    ASP.Net Core使用Ajax局部更新
    ASP.NET Core中的jQuery Unobtrusive Ajax帮助器
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/11011870.html
Copyright © 2020-2023  润新知