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):将 ...
随机推荐
- [HDU 5542] The Battle of Chibi
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5542 [算法] 树状数组优化DP [代码] #include<bits/stdc++.h&g ...
- Redis学习笔记(一) 初识 Redis
简介 我所在的公司是一个以线下业务为主的公司,软件这一块的东西可以说是手工作坊,技术上的东西全靠大家自己折腾.最近也是觉得自己在社会主义的怀抱里安逸了太久,要提高思想政治觉悟,不能忘了资本主义的黑暗, ...
- js数组及数组对象的遍历
一 数组遍历 方法一:for循环 方法二:forEach遍历 forEach遍历数组 性能低于for循环,且不可使用break中断循环,也不能使用return返回外层函数 arr.forEach(fu ...
- JS装饰器模式
装饰器模式:在不改变原对象的基础上,通过对其进行包装拓展(添加属性或者方法),保护原有功能的完整性需要条件:原对象,新内容(属性/方法)个人理解:重新实现一下,原对象的方法,在方法内容,先执行原对象的 ...
- Unity 向量点乘、叉乘
向量点乘计算角度,向量叉乘计算方位 a,b为向量 点乘计算公式:a x b = |a| x |b| x cosθ 叉乘计算公式:a x b = |a| x |b| x sinθ
- 如何在使用layer.prompt在输入值为空的情况下点击确定继续执行逻辑?
突然发现在使用LayUI时,用到弹出层layer.prompt时,如果文本框输入值是空的话点击确定没有反应,不能向下执行. 但是我又需要在这种情况下去继续执行判断或逻辑时该怎么做?? 示例:原代码如下 ...
- 使用json_decode无法解析json
在接入合作方接口时,遇到一个json无法解析出来代码如下: <?php $res='{"resultcode":007,"resMsg":"!& ...
- JTree知识小点
创建一个新节点 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新节点"); 被选中的节点 Default ...
- [BOI2007]摩基亚
题目:洛谷P4390.BZOJ1176. 题目大意: 给你一个\(W\times W\)的矩阵,初始每个数都为\(S\).现在有若干操作: 1. 给某个格子加上一个值:2. 询问某个子矩阵的值的和:3 ...
- POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...