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格式)模型文件。具体操作步骤如下详细介绍。




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

编写XAML代码如下:
<UserControl x:Class="Xbim.WinformsSample.WinformsAccessibleControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:presentation="http://schemas.Xbim.com/Presentation"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800"
x:Name="MainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid Name="MainFrame">
<presentation:DrawingControl3D x:Name="DrawingControl"
x:FieldModifier="public"
Model ="{Binding ModelProvider.ObjectInstance}"
Focusable="True"
Width="Auto"
Height="Auto"
SelectedEntityChanged="DrawingControl_SelectedEntityChanged"
ModelOpacity="1">
</presentation:DrawingControl3D>
</Grid>
</UserControl>
其中第12行,引用了 xBIM官方提供的 模型浏览器组件。显示效果如下:

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

后台逻辑:在第四步骤中创建了一个WPF用户控件,在此处实例化一个对象
private WinformsAccessibleControl _wpfControl;
在构造函数中初始化该对象并将对象添加到 controlHost 中
public FormExample(ILogger logger = null)
{
InitializeComponent(); Logger = logger ?? new LoggerFactory().CreateLogger<FormExample>(); IfcStore.ModelProviderFactory.UseHeuristicModelProvider(); _wpfControl = new WinformsAccessibleControl();
_wpfControl.SelectionChanged += _wpfControl_SelectionChanged; controlHost.Child = _wpfControl;
}
运行效果如下:

完整的示例代码如下:
using System;
using System.Linq;
using System.Windows.Forms; using Microsoft.Extensions.Logging; using Xbim.Common;
using Xbim.Ifc;
using Xbim.Ifc4.Interfaces;
using Xbim.ModelGeometry.Scene; namespace Xbim.WinformsSample
{
public partial class FormExample : Form
{
private WinformsAccessibleControl _wpfControl; int starting = -; protected ILogger Logger { get; private set; } public FormExample(ILogger logger = null)
{
InitializeComponent(); Logger = logger ?? new LoggerFactory().CreateLogger<FormExample>(); IfcStore.ModelProviderFactory.UseHeuristicModelProvider(); _wpfControl = new WinformsAccessibleControl();
_wpfControl.SelectionChanged += _wpfControl_SelectionChanged; controlHost.Child = _wpfControl;
} private void _wpfControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
var ent = e.AddedItems[] as IPersistEntity;
txtEntityLabel.Text = ent == null ? "" : ent.EntityLabel.ToString();
} /// <summary>
/// 打开BIM(.ifc格式)文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnLoadBimFile_Click(object sender, EventArgs e)
{
var dlg = new OpenFileDialog();
dlg.Filter = @"IFC Files|*.ifc;*.ifczip;*.ifcxml|Xbim Files|*.xbim";
dlg.FileOk += (s, args) =>
{
LoadXbimFile(dlg.FileName);
};
dlg.ShowDialog(this);
} /// <summary>
/// 查看模型实体标签
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnNext_Click(object sender, EventArgs e)
{
var mod = _wpfControl.ModelProvider.ObjectInstance as IfcStore;
if (mod == null)
return; var found = mod.Instances.OfType<IIfcProduct>().FirstOrDefault(x => x.EntityLabel > starting);
_wpfControl.SelectedElement = found; if(found != null)
{
starting = found.EntityLabel;
}
else
{
starting = -;
}
} /// <summary>
/// 加载BIM(.ifc格式)文件
/// </summary>
/// <param name="dlgFileName"></param>
private void LoadXbimFile(string dlgFileName)
{
// TODO: should do the load on a worker thread so as not to lock the UI.
// 如果加载的模型文件较大,耗时可能较长,建议使用后要程序处理,给用户一个好的使用体验。 Clear(); var model = IfcStore.Open(dlgFileName);
if (model.GeometryStore.IsEmpty)
{
// 使用 xBIM 几何引擎创建 GeometryEngine 对象
try
{
var context = new Xbim3DModelContext(model); context.CreateContext(); // TODO: SaveAs(xbimFile); // so we don't re-process every time
}
catch (Exception geomEx)
{
Logger.LogError(, geomEx, "Failed to create geometry for {filename}", dlgFileName);
}
}
_wpfControl.ModelProvider.ObjectInstance = model;
} public void Clear()
{
if (_wpfControl.ModelProvider != null)
{
var currentIfcStore = _wpfControl.ModelProvider.ObjectInstance as IfcStore;
currentIfcStore?.Dispose(); _wpfControl.ModelProvider.ObjectInstance = null;
}
}
}
}
xBIM 实战04 在WinForm窗体中实现IFC模型的加载与浏览的更多相关文章
- xBIM 实战03 使用WPF技术实现IFC模型的加载与浏览
系列目录 [已更新最新开发文章,点击查看详细] WPF应用程序在底层使用 DirectX ,无论设计复杂的3D图形(这是 DirectX 的特长所在)还是绘制简单的按钮与文本,所有绘图工作都是 ...
- C#将exe运行程序嵌入到自己的winform窗体中
以下例子是将Word打开,然后将它嵌入到winform窗体中,效果如下图:C将exe运行程序嵌入到自己的winform窗体中 - kingmax_res - iSport注意:该方法只适用于com的e ...
- 关于WinForm引用WPF窗体---在Winform窗体中使用WPF控件
项目中有个界面展示用WPF实现起来比较简单,并且能提供更酷炫的效果,但是在WinForm中使用WPF窗体出现了问题,在网上找了一下有些人说Winform不能引用WPF的窗体,我就很纳闷,Win32都能 ...
- 在Winform窗体中使用WPF控件(附源码)
原文:在Winform窗体中使用WPF控件(附源码) 今天是礼拜6,下雨,没有外出,闲暇就写一篇博文讲下如何在Winform中使用WPF控件.原有是我在百度上搜索相关信息无果,遂干脆动手自己实现. W ...
- 深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 3
备注: 因为文章太长,所以将它分为三部分,本文是第三部分. 第一部分:深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1 第二部分:深入浅出经典面试题:从浏览器中输入URL ...
- 从浏览器中输入URL到页面加载的发生了什么-转载
转:https://www.cnblogs.com/confach/p/10050013.html 背景 “从浏览器中输入URL到页面加载的发生了什么“,这是一道经典的面试题,涉及到的知识面非常多,但 ...
- 【ASP.NET Core】EF Core - “影子属性” 深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1
[ASP.NET Core]EF Core - “影子属性” 有朋友说老周近来博客更新较慢,确实有些慢,因为有些 bug 要研究,另外就是老周把部分内容转到直播上面,所以写博客的内容减少了一点. ...
- Asp.Net Core 项目实战之权限管理系统(8) 功能菜单的动态加载
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- EXT中的iconCls 图标加载
刚刚遇到了个奇怪的问题. 我用 在主页面用TAB autoLoad:{url:link, nocache: true, scripts:true} 加载页面Student.jsp, 郁闷,FF可以正常 ...
随机推荐
- 英语发音规则---G字母
英语发音规则---G字母 一.总结 一句话总结: 1.G发[g]音? bag [bæg] n. 袋:猎获物 go [gəʊ] vi. 走:达到 garden ['gɑːd(ə)n] n. 花园 gla ...
- [JavaEE] Maven简介
转载自:百度 http://baike.baidu.com/view/336103.htm?fr=aladdin 一.简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构 ...
- htmlunit 简单操作
首先我们新建一个Maven普通客户端项目,然后打开pom.xml 引入htmlunit支持: <dependency> <groupId>net.sourceforge.htm ...
- 深入了解React组件重新渲染的条件和生命周期
React组件rerender的真正条件 当前组件的State中的属性改变时且当前组件的shouldcomponentupdate返回true,那么当前组件会rerender 组件的props中的任一 ...
- ddk安装失败后的处理
7600.16385.1版本的DDK,在xp的本上死活按不上,怎么办呢?自己就把其他机器上安装的DDK目录,拷贝过来. 怎么建编译环境呢? 查看x86 Checked Build Environmen ...
- Unity 向量点乘、叉乘
向量点乘计算角度,向量叉乘计算方位 a,b为向量 点乘计算公式:a x b = |a| x |b| x cosθ 叉乘计算公式:a x b = |a| x |b| x sinθ
- 从源码中查看当前android版本
从文件build/core/version_defaults.mk查找PLATFORM_VERSION例如:PLATFORM_VERSION.OPM1 := 8.1.0
- LeetCode Golang 7. 整数反转
7. 整数反转 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. Tips : Math包给出的类型大小的边界: // Integer limit values. const ...
- Pyhton学习——Day48
# 转载:http://www.cnblogs.com/yuanchenqi/articles/6437362.html#python关于mysql的API--pymysql模块# 执行sql语句# ...
- IOS - IOS之同步请求、异步请求、GET请求、POST请求(转载)
转载:http://www.open-open.com/lib/view/open1355055986679.html 1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务 ...