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):将 ...
随机推荐
- 英语发音规则---B字母
英语发音规则---B字母 一.总结 一句话总结: 1.B发[b]音? bike [baɪk] n. 自行车 bus [bʌs] n. 公共汽车 bag [bæg] n. 袋:猎获物 baby ['be ...
- kaggle 中使用ipython
# pandas import pandas as pd from pandas import Series,DataFrame # numpy, matplotlib, seaborn import ...
- PHPMailer使用说明
PHPMailer是一个用来发送电子邮件的函数包,远比PHP提供的mail()方便易用. 邮件格式说明 一封普通的电子邮件,通常是由发件人.收件人.抄送人.邮件标题.邮件内容.附件等内容构成.以下是一 ...
- Oracle中的数据字典技术及常用数据字典总结
一.Oracle数据字典 数据字典是Oracle存放有关数据库信息的地方,其用途是用来描述数据的.比如一个表的创建者信息,创建时间信息,所属表空间信息,用户访问权限信息等.当用户在对数据库中的数据进行 ...
- COM基础
为什么说COM的可重用性是建立在二进制级别? COM本身是语言无关,它的标准建立在二进制级别.对于使用COM组件的客户程序,它只需要要使用的COM对象信息就可以通过COM库的帮助创建和使用COM对象, ...
- uni-app 自定义扫码界面
二维码扫描,已经成为当下一款应用不可或缺,同时也是用户习以为常的功能了.uni-app 为我们提供了扫码 API ,直接调用即可. 需求场景 在实际开发中,平台提供的默认扫码界面,并不能满足一些自定义 ...
- What is the difference between arguments and parameters?
What is the difference between arguments and parameters? Parameters are defined by the names that ap ...
- DB2导出表结构、表数据小结
一.DB2命令行导出数据库全库表结构 ① Win+R进入到DB2安装目录的BIN目录下,执行命令:DB2CMD,进入到DB2 CLP窗口. 命令:DB2CMD ② 创建一个data文件夹 命令:MKD ...
- Kattis - mixedfractions
Mixed Fractions You are part of a team developing software to help students learn basic mathematics. ...
- [NOIP2004提高组]虫食算
题目:洛谷P1092.codevs1064.Vijos P1099. 题目大意:给你一个$n$进制.每个数都是$n$位的三个数a,b,c,这些数的数位由字母表示(共$n$个字母,从‘A’开始),所有数 ...