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可以正常 ...
随机推荐
- AngularJS 下拉列表demo
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- POJ 3020 Hungary
一道建图题-- // by SiriusRen #include <cstdio> #include <cstring> using namespace std; #defin ...
- 9-21 调试javaweb 数据库连接感想
如何找bug 一步步调试 数据库链接写一个简单的 test 数据库操作 sql语句 写一个类 测试一下 不要忽略细节 最后页面的显示 html "/head"少一个"/& ...
- js前台编码,asp.net后台解码 防止前台传值到后台为乱码
js编码: encodeURI() 后台解码:HttpUtility.UrlDecode()
- 开发辅助 | 前端开发工程师必懂的 UI 知识
移动 UI 设计的世界 ... 1.屏幕尺寸 屏幕大小,指屏幕对角线的长度,而不是屏幕的宽度或高度: 单位为英寸 如 iPhone 7 屏幕尺寸为 4.7 英寸:三星 S6 屏幕尺寸为 ...
- js数组及数组对象的遍历
一 数组遍历 方法一:for循环 方法二:forEach遍历 forEach遍历数组 性能低于for循环,且不可使用break中断循环,也不能使用return返回外层函数 arr.forEach(fu ...
- UVa 10106 Product 【大数相乘】WA
虽然是错的代码,但是还是想贴出来,最开始WA发现是没有考虑到乘积为0的情况,后来把a*0,0*a,a*0---0(若干个0),0--0(若干个0)*a都考虑进去了:可是还是WA,实在不懂先留在这儿. ...
- Pyhton学习——Day47
# 转载:http://www.cnblogs.com/yuanchenqi/articles/6357507.html# 外键:一种约束条件,与主键对应# 主表:被绑定的表:字表# 外键约束:# - ...
- CentOS 7.5安装pycharm
环境 安装环境: windows 10 Pro CentOS Linux release 7.6.1810 (Core) VMWare Workstation 15 Pro 安装图形化界面包 首先更新 ...
- EXGSBS模板
EXBSGS模板 我之前把有一处b和c弄反了,有点困...然后调了半天 (exbsgs比excrt简单多了) 求x的最小正整数解 原式子拆成 在bsgs中,保证a,b互质,这样求出的逆元挪过去才对 但 ...