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可以正常 ...
随机推荐
- centos + nodejs + egg2.x 开发微信分享功能
本文章发到掘金上,请移步阅读: https://juejin.im/post/5cf10b02e51d45778f076ccd
- php.ini控制文件上传大小配置项
; Whether to allow HTTP file uploads.file_uploads = On ; Temporary directory for HTTP uploaded files ...
- 最简单的启动并连接一个redis的docker容器
启动一个容器: $ sudo docker run --name <name> -d redis 连接一个容器: sudo docker run -it --link <name&g ...
- Swagger中添加Token验证
1.该连接链接到api中基本的swagge功能:http://www.cnblogs.com/hhhh2010/p/5234016.html 2.在swagger中使用验证(这里使用密码验证模式)ht ...
- linux下服务启动脚本
#!/usr/bin/env python# -*- coding: utf-8 -*-# @File : deployment.py# @Author: Anthony.waa# @Date : 2 ...
- Hua Wei 机试题目一
一.身份证号码验证 题目描述: 我国公民的身份证号码特点如下:1. 长度为18位:2. 第1-17位只能为数字:3. 第18位可以是数字或者小写英文字母x.4. 身份证号码的第7~14位表示持有人生日 ...
- javascript中DOM基础知识介绍
1.1. 基本概念 1.1.1. DOM DOM Document Object Model 文档对象模型 就是把HTML文档模型化,当作对象来处理 DOM提供的一系列属性和方法可以 ...
- [转]opencv学习资料
转自:http://blog.csdn.net/poem_qianmo/article/details/20537737 1:Mat imread(const string& filename ...
- 在centos6.5上升级php-libxml版本到2.9.0
当前系统,软件版本说明: php libxml glibc 2.12 zlib xz-libs 需求: 应开发的需求,线上环境,php-libxml版本升级到2.8以上. 升级步骤:1.安装工具集 y ...
- Django路由URL
URL配置(URLconf)就像Django所支撑网站的目录.URL与要为该URL调用的视图函数之间的映射表. URLconf配置 样式: from django.conf.urls import u ...