xBIM 实战03 使用WPF技术实现IFC模型的加载与浏览
因为 DirectX 能理解可由显卡直接渲染的高层元素,如纹理和渐变,所以 DirectX 效率更高。而 GDI/GDI+不理解这些高层元素,因此必须将他们转换成逐像素指令,而通过现代显卡渲染这些指令更慢。
主要业务逻辑如下:
/// <summary>
/// 加载模型文件
/// </summary>
/// <param name="modelFileName"></param>
public void LoadAnyModel(string modelFileName)
{
var fInfo = new FileInfo(modelFileName);
if (!fInfo.Exists)
return; if (fInfo.FullName.ToLower() == GetOpenedModelFileName())
return; // 没有撤回功能;如果在这一点之后失败,那么应该关闭当前文件。
CloseAndDeleteTemporaryFiles();
SetOpenedModelFileName(modelFileName.ToLower());
ProgressStatusBar.Visibility = Visibility.Visible;
SetWorkerForFileLoad(); var ext = fInfo.Extension.ToLower();
switch (ext)
{
case ".ifc": // Ifc 文件
case ".ifcxml": // IfcXml 文件
case ".ifczip": // zip 文件,包含 xbim 或者 ifc 文件
case ".zip": // zip 文件,包含 xbim 或者 ifc 文件
case ".xbimf":
case ".xbim":
_loadFileBackgroundWorker.RunWorkerAsync(modelFileName);
break;
default:
Logger.LogWarning("Extension '{extension}' has not been recognised.", ext);
break;
}
}
其中调用的主要方法如下:
/// <summary>
/// 整理所有打开的文件并关闭所有打开的模型
/// </summary>
private void CloseAndDeleteTemporaryFiles()
{
try
{
if (_loadFileBackgroundWorker != null && _loadFileBackgroundWorker.IsBusy)
{
_loadFileBackgroundWorker.CancelAsync(); //通知线程取消操作
} SetOpenedModelFileName(null);
if (Model != null)
{
Model.Dispose();
ModelProvider.ObjectInstance = null;
ModelProvider.Refresh();
} if (!(DrawingControl.DefaultLayerStyler is SurfaceLayerStyler))
{
SetDefaultModeStyler(null, null);
}
}
finally
{
if (!(_loadFileBackgroundWorker != null && _loadFileBackgroundWorker.IsBusy && _loadFileBackgroundWorker.CancellationPending)) //它仍然在运行,但已经取消了
{
if (!string.IsNullOrWhiteSpace(_temporaryXbimFileName) && File.Exists(_temporaryXbimFileName))
{
File.Delete(_temporaryXbimFileName);
}
_temporaryXbimFileName = null;
}
else
{
//它将在工作线程中清除
}
}
}
private void SetOpenedModelFileName(string ifcFilename)
{
_openedModelFileName = ifcFilename;
// 尝试通过用于多线程的委托更新窗口标题
Dispatcher.BeginInvoke(new Action(delegate
{
Title = string.IsNullOrEmpty(ifcFilename)
? "Xbim Xplorer"
: "Xbim Xplorer - [" + ifcFilename + "]";
}));
}
private void SetWorkerForFileLoad()
{
_loadFileBackgroundWorker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_loadFileBackgroundWorker.ProgressChanged += OnProgressChanged;
_loadFileBackgroundWorker.DoWork += OpenAcceptableExtension;
_loadFileBackgroundWorker.RunWorkerCompleted += FileLoadCompleted;
}
private void OnProgressChanged(object s, ProgressChangedEventArgs args)
{
if (args.ProgressPercentage < || args.ProgressPercentage > )
return; Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Send,
new Action(() =>
{
ProgressBar.Value = args.ProgressPercentage;
StatusMsg.Text = (string)args.UserState;
})); }
private void OpenAcceptableExtension(object s, DoWorkEventArgs args)
{
var worker = s as BackgroundWorker;
var selectedFilename = args.Argument as string; try
{
if (worker == null)
throw new Exception("Background thread could not be accessed");
_temporaryXbimFileName = Path.GetTempFileName();
SetOpenedModelFileName(selectedFilename);
var model = IfcStore.Open(selectedFilename, null, null, worker.ReportProgress, FileAccessMode);
if (_meshModel)
{
// 匹配直接模型
if (model.GeometryStore.IsEmpty)
{
try
{
var context = new Xbim3DModelContext(model); if (!_multiThreading)
context.MaxThreads = ;
#if FastExtrusion
context.UseSimplifiedFastExtruder = _simpleFastExtrusion;
#endif
SetDeflection(model);
// 升级到新的几何图形表示,使用默认的三维模型
context.CreateContext(worker.ReportProgress, App.ContextWcsAdjustment);
}
catch (Exception geomEx)
{
var sb = new StringBuilder();
sb.AppendLine($"Error creating geometry context of '{selectedFilename}' {geomEx.StackTrace}.");
var newException = new Exception(sb.ToString(), geomEx);
Logger.LogError(, newException, "Error creating geometry context of {filename}", selectedFilename);
}
} // 匹配引用
foreach (var modelReference in model.ReferencedModels)
{
// 根据需要创建联合几何体上下文
Debug.WriteLine(modelReference.Name);
if (modelReference.Model == null)
continue;
if (!modelReference.Model.GeometryStore.IsEmpty)
continue;
var context = new Xbim3DModelContext(modelReference.Model);
if (!_multiThreading)
context.MaxThreads = ;
#if FastExtrusion
context.UseSimplifiedFastExtruder = _simpleFastExtrusion;
#endif
SetDeflection(modelReference.Model);
// 升级到新的几何图形表示,使用默认的三维模型
context.CreateContext(worker.ReportProgress, App.ContextWcsAdjustment);
}
if (worker.CancellationPending)
// 如果已请求取消,则不要打开结果文件
{
try
{
model.Close();
if (File.Exists(_temporaryXbimFileName))
{
File.Delete(_temporaryXbimFileName);
} _temporaryXbimFileName = null;
SetOpenedModelFileName(null);
}
catch (Exception ex)
{
Logger.LogError(, ex, "Failed to cancel open of model {filename}", selectedFilename);
}
return;
}
}
else
{
Logger.LogWarning("Settings prevent mesh creation.");
}
args.Result = model;
}
catch (Exception ex)
{
var sb = new StringBuilder();
sb.AppendLine($"Error opening '{selectedFilename}' {ex.StackTrace}.");
var newException = new Exception(sb.ToString(), ex);
Logger.LogError(, ex, "Error opening {filename}", selectedFilename);
args.Result = newException;
}
}
private void FileLoadCompleted(object s, RunWorkerCompletedEventArgs args)
{
if (args.Result is IfcStore)
{
// 这将触发将模型加载到视图中的事件
ModelProvider.ObjectInstance = args.Result;
ModelProvider.Refresh();
ProgressBar.Value = ;
StatusMsg.Text = "Ready";
AddRecentFile();
}
else
{
var errMsg = args.Result as string;
if (!string.IsNullOrEmpty(errMsg))
{
MessageBox.Show(this, errMsg, "Error Opening File", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.None, MessageBoxOptions.None);
} var exception = args.Result as Exception;
if (exception != null)
{
var sb = new StringBuilder(); var indent = "";
while (exception != null)
{
sb.AppendFormat("{0}{1}\n", indent, exception.Message);
exception = exception.InnerException;
indent += "\t";
}
MessageBox.Show(this, sb.ToString(), "Error Opening Ifc File", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.None, MessageBoxOptions.None);
}
ProgressBar.Value = ;
StatusMsg.Text = "Error/Ready";
SetOpenedModelFileName("");
}
FireLoadingComplete(s, args);
}
/// <summary>
/// 模型文件加载完成事件
/// </summary>
public event LoadingCompleteEventHandler LoadingComplete; private void FireLoadingComplete(object s, RunWorkerCompletedEventArgs args)
{
if (LoadingComplete != null)
{
LoadingComplete(s, args);
}
}
xBIM 实战03 使用WPF技术实现IFC模型的加载与浏览的更多相关文章
- xBIM 实战04 在WinForm窗体中实现IFC模型的加载与浏览
系列目录 [已更新最新开发文章,点击查看详细] WPF底层使用 DirectX 进行图形渲染.DirectX 能理解可由显卡直接渲染的高层元素,如纹理和渐变,所以 DirectX 效率更高. ...
- WPF防止界面卡死并显示加载中效果
原文:WPF防止界面卡死并显示加载中效果 网上貌似没有完整的WPF正在加载的例子,所以自己写了一个,希望能帮到有需要的同学 前台: <Window x:Class="WpfApplic ...
- [WPF自定义控件库] 让Form在加载后自动获得焦点
原文:[WPF自定义控件库] 让Form在加载后自动获得焦点 1. 需求 加载后让第一个输入框或者焦点是个很基本的功能,典型的如"登录"对话框.一般来说"登录" ...
- 【Android编程实战】源码级免杀_Dex动态加载技术_Metasploit安卓载荷傀儡机代码复现
/文章作者:MG193.7 CNBLOG博客ID:ALDYS4 QQ:3496925334/ 在读者阅读本文章前,建议先阅读笔者之前写的一篇对安卓载荷的分析文章 [逆向&编程实战]Metasp ...
- 【WPF学习】第四章 加载和编译XAML
前面已经介绍过,尽管XAML和WPF这两种技术具有相互补充的作用,但他们也是相互独立的.因此,完全可以创建不使用XAML和WPF应用程序. 总之,可使用三种不同的编码方式来创建WPF应用程序: 只使用 ...
- HTML5的页面资源预加载技术(Link prefetch)加速页面加载
不管是浏览器的开发者还是普通web应用的开发者,他们都在做一个共同的努力:让Web浏览有更快的速度感觉.有很多已知的技术都可以让你的网站速度变得更快:使用CSS sprites,使用图片优化工具,使用 ...
- 那些H5用到的技术(1)——素材加载
编码环境前言什么时候用到素材加载?loading提示,让用户等待图片的加载音频的加载利用神器PreloadJS总结 编码环境 Sublime Text 3 插件包括: Autoprefixer 自动补 ...
- wpf prism4 出现问题:无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。
WPF Prism 框架 程序 出现 问题: 无法加载一个或多个请求的类型.有关更多信息,请检索 LoaderExceptions 属性. 1.开始以为是配置的问题,找了半天,最后原来是有个依赖类库没 ...
- tvtk管线技术、数据集与数据加载
管线技术也称流水线技术(Pipeline)每个对象只实现相对简单的任务,整个管线进行复杂的可视化处理在tvtk中分为可视化管线和图形管线 可视化管线(Visualization Pipeline):将 ...
随机推荐
- Linux,Docker,Jenkins No such file or directory
你们先休息下,我先哭哭! 今天在做交接项目的bug修改的时候,在创建文件的时候报错 No such file or directory 然后跟着路径去linux中查看了该路径,但确实存在,并且权限都是 ...
- c/c++ 比较好的开源框架
作者:EZLippi链接:https://www.zhihu.com/question/19823234/answer/31632919来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 循环引用的weak和assgin
__weak 当对象销毁后weakSelf指向的地址为nil __unsafe_unretained 挡圈对象销毁后,weakSelf执行的地址为不变,而地址对应对象已经销毁,再次访问该对象就崩溃,相 ...
- Spring《二》 Bean的生命周期
Bean初始化 1.bean中实现public void init():方法,config.xml中增加init-method="init" 属性. 2.bean实现接口Initi ...
- Ubuntu16.04下沙盒数据导入到 Neo4j 数据库(图文详解)
不多说,直接上干货! 参考博客 http://blog.csdn.net/u012318074/article/details/72793914 (表示感谢) 前期博客 Neo4j沙盒实验申请过 ...
- Windows 安装 MySQL8
MySQL8下载地址:https://dev.mysql.com/downloads/mysql/ 解压到安装目录 新建配置文件my.ini [mysqld]# 设置mysql的安装目录basedir ...
- android UI卡顿问题学习
转自https://blog.csdn.net/joye123/article/details/79425398 https://blog.csdn.net/zhenjie_chang/article ...
- Tomcat转jboss踩的那些坑
问题背景 今天发版本,是一个httpclient的跳转(由于公司网络原因,所以对外网的访问都经过这个代理服务出去). 问题原因 之前的开发一直在window系统的tomcat服务器上进行的,对jbos ...
- UNP学习笔记4——I/O复用:select和poll函数
1 概述 之间的学习中发现,传统的阻塞式系统调用不仅浪费进程运行时间,而且会带来狠毒问题.因此进程需要有一种预先告知内核的能力,使得内核一旦发现进程指定的一个或者多个I/O条件就绪,它就通知进程.这个 ...
- 第一章 关于python
Python简介 Python是什么? python的创始人为吉多·范罗苏姆(Guido van Rossum). “Python is a great object-oriented, int ...