﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-eryar</title><link>http://www.cppblog.com/eryar/</link><description>PipeCAD - Plant Piping Design Software. &lt;br&gt;
PlantAssistant - Translate AVEVA RVM/SP3D VUE to glTF, STEP, etc.</description><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 16:19:22 GMT</lastBuildDate><pubDate>Thu, 16 Apr 2026 16:19:22 GMT</pubDate><ttl>60</ttl><item><title>解析SP3D VUE和PDMS RVM文件-PlantAssistant</title><link>http://www.cppblog.com/eryar/archive/2025/11/09/PlantAssistant_Background.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sun, 09 Nov 2025 12:42:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2025/11/09/PlantAssistant_Background.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230477.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2025/11/09/PlantAssistant_Background.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230477.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230477.html</trackback:ping><description><![CDATA[<h2>引言</h2><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;">依托主流工厂设计软件数字化交付数据文件，AVEVA公司PDMS/E3D的RVM和Intergraph公司SP3D的VUE：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/534255/202511/534255-20251109203432086-1214758008.png" alt="Model Files" loading="lazy" style="margin: 0px; padding: 0px; border: 0px; max-width: 700px; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;">PlantAssistant可以解析VUE和RVM中三维模型数据，属性数据，保留设计目录树，并可以将这些信息转换成通用的三维文件格式，如GLTF, OBJ等，为数字化交付提供服务。PlantAssistant三维浏览功能免费使用，为三维模型评审提供一个轻量化的工具。</p><h2>三维视图设置</h2><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;">根据用户反馈，在PlantAssistant中增加视图相关设置选项，如设置是否显示坐标轴、视图方块、三维视图背景，可以设置背景颜色，还可以设置一张图片作为三维视图背景。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/534255/202511/534255-20251109203452885-1051423704.png" alt="Background Options" loading="lazy" style="margin: 0px; padding: 0px; border: 0px; max-width: 700px; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;">另外还修复中文显示乱码的问题，包括设计目录树上名称显示中文乱码，属性中文乱码，以及导出GLTF中设计目录树名称及属性中文乱码问题。</p><h2>下载PlantAssistant</h2><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, Arial, sans-serif; background-color: #ffffff;">PlantAssistant软件在PipeCAD QQ群文件中下载，欢迎大家下载使用反馈意见。<br style="margin: 0px; padding: 0px;" />欢迎大家加入PipeCAD QQ交流群 964851855，交流软件问题、心得：<br style="margin: 0px; padding: 0px;" /><img src="https://img2024.cnblogs.com/blog/534255/202511/534255-20251109203513138-447838891.png" alt="PipeCAD QQ" loading="lazy" style="margin: 0px; padding: 0px; border: 0px; max-width: 700px; height: auto !important;" /></p><img src ="http://www.cppblog.com/eryar/aggbug/230477.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2025-11-09 20:42 <a href="http://www.cppblog.com/eryar/archive/2025/11/09/PlantAssistant_Background.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PlantAssistant-免费查看RVM/VUE</title><link>http://www.cppblog.com/eryar/archive/2025/10/25/PlantAssistant_0_1_6.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 25 Oct 2025 09:24:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2025/10/25/PlantAssistant_0_1_6.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230475.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2025/10/25/PlantAssistant_0_1_6.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230475.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230475.html</trackback:ping><description><![CDATA[<h2>引言</h2>
<p>依托主流工厂设计软件数字化交付数据文件，AVEVA公司PDMS/E3D的RVM和Intergraph公司SP3D的VUE：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251025171837365-486455260.png" alt="image" /></section>
<p>我们想把工厂数字化助手PlantAssistant做成大家设计工作中的一个好帮手。这是我们构想的PlantAssistant的一些功能，主要是对工厂模型进行审查、模型的转换和复用及自动出图功能。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251025171843575-613472995.png" alt="image" /></section>
<p>通过解析这两个主流设计软件的数据，可以实现工厂模型的三维可视化，从而进行模型的审查。现在发布一个版本，可以用来免费查看RVM和VUE的三维模型，并且轻量小巧。</p>
<h2>RVM&amp;VUE</h2>
<p>PlantAssistant支持浏览RVM模型及查看对应的属性，点击三维模型对象，会自动定位到设计导航树：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251025171901508-305225204.png" alt="image" /></section>
<p>PlantAssistant支持浏览VUE模型，暂不支持属性数据的查看，正在开发中，下个版本将会支持。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251025171908723-848258663.png" alt="image" /></section>
<h2>下载PlantAssistant</h2>
<p>PlantAssistant软件在PipeCAD QQ群文件中下载，欢迎大家下载使用反馈意见。欢迎大家加入PipeCAD QQ交流群 964851855，交流软件问题、心得：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101058443-359405766.png" alt="image" /></section><img src ="http://www.cppblog.com/eryar/aggbug/230475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2025-10-25 17:24 <a href="http://www.cppblog.com/eryar/archive/2025/10/25/PlantAssistant_0_1_6.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>武汉图核科技</title><link>http://www.cppblog.com/eryar/archive/2025/10/20/TUHE_TECH.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Mon, 20 Oct 2025 02:59:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2025/10/20/TUHE_TECH.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230473.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2025/10/20/TUHE_TECH.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230473.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230473.html</trackback:ping><description><![CDATA[<h1 data-tool="mdnice编辑器"><span class="js_darkmode__1">新的名字</span></h1>
<p class="js_darkmode__2" data-tool="mdnice编辑器">以前的名字是英语单词音译过来的，没有什么具体含义，也不容易看出是做什么的。中国人还是取个中文名好一些，于是想换个名字，要言简意赅，简单好记。不擅长取名，找AI来帮忙：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100905835-1519304666.png" alt="image" /></section>
<p class="js_darkmode__3" data-tool="mdnice编辑器">一眼相中了图核科技这个名字，图核科技有图形核心、技术硬核意。&#8220;图&#8221;点明行业，&#8221;核&#8220;强调深耕图形核心技术，软件产品是设计工作的核心工具等<span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;section&quot;,&quot;attributes&quot;:{&quot;data-tool&quot;:&quot;mdnice编辑器&quot;,&quot;data-website&quot;:&quot;https://www.mdnice.com&quot;,&quot;style&quot;:&quot;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, 'Microsoft YaHei', PingFangSC-regular, serif;font-size: 16px;color: #000000;line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;data-tool&quot;:&quot;mdnice编辑器&quot;,&quot;style&quot;:&quot;color: #000000;font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">，简单明了</span>。直接在政务中心网站在线办理，一天就办好了，还是很方便的，也算办成一件称心的事情。新的名字，新的起点！</p>
<h2 data-tool="mdnice编辑器"><span class="js_darkmode__4">产品简介</span></h2>
<h3 data-tool="mdnice编辑器"><span class="js_darkmode__5">工厂数字化助手 PlantAssistant</span></h3>
<p class="js_darkmode__6" data-tool="mdnice编辑器">自2012年开发出RvmTranslator以来，不断改进优化，除了支持AVEVA的RVM文件解析以外，还支持Intergraph SP3D的VUE文件解析。PlantAssistant三维浏览功能免费使用，为用户提供一个轻量级的模型审查工具。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100919080-1114622036.png" alt="image" /></section>
<p class="js_darkmode__7" data-tool="mdnice编辑器">PlantAssistant完整解析RVM/VUE中的几何模型信息、属性信息等，能转换成通用的3D文件格式，如GLTF、STEP等，实现跨平台数据共享，为工厂数字化交付提供支持。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100930286-620241659.png" alt="image" /></section>
<p class="js_darkmode__8" data-tool="mdnice编辑器">RVM/ATT和VUE/MDB中包含了工厂几何模型数据和属性信息，进一步发掘这些数据，可以实现业务对象级的数据复用，可以统一PDMS/SP3D自动出图等，成为公司数字化的得力助手。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100937740-266838066.png" alt="image" /></section>
<section>所谓模型复用是指通过PlantAssistant将RVM/ATT等数据转换到相应的设计软件中，使数据不再是单向的，而是可以循环滚动起来，让数据发挥更大价值。</section>
<h3 data-tool="mdnice编辑器"><span class="js_darkmode__9">管道轴测图引擎 IsoAlgo</span></h3>
<p class="js_darkmode__10" data-tool="mdnice编辑器">管道轴测图（ISO图）是管道制作安装所需的重要图纸，其中管件符号是固定大小，管子长度可变的一种非比例投影的出图方式。目前国际出图标准程序是被Intergraph收购的Alias公司的ISOGEN。我们自研管道ISO图自动出图程序IsoAlgo，经过多年迭代开发，IsoAlgo生成的管道ISO图尺寸标注及件号标注等标注信息都做了优化处理，尽量避免重叠。出图速度快，效率高。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100945328-1438446986.png" alt="image" /></section>
<p class="js_darkmode__11" data-tool="mdnice编辑器">IsoAlgo提供丰富的配置选项，满足用户个性化需求。通过配置可以生成管道材料表、焊点表等。IsoAlgo已经应用于实际项目，将继续优化，提高出图质量。</p>
<h3 data-tool="mdnice编辑器"><span class="js_darkmode__12">三维智能出图软件 AutoDraft</span></h3>
<p class="js_darkmode__13" data-tool="mdnice编辑器">工程设计单位在工厂详细设计阶段时，采用传统方式出图花费大量时间，标注叠加难以处理，一般设计人员很难使用Draft模块完成出图工作，无法做到所见所得的设计思路，会有平面图纸不准确的情况存在。</p>
<p class="js_darkmode__14" data-tool="mdnice编辑器">基于SHT 3052-2014和SY/T0003-2012制图标准，详细分析了专业出图的特点，精细打造出三维智能出图软件AutoDraft(简称AD出图)软件到市场中，得到用户的好评。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017100952373-18286715.png" alt="image" /></section>
<p class="js_darkmode__15" data-tool="mdnice编辑器">众多工程师在项目中使用AD出图软件,软件的使用方式和软件效率得到了很高的评价，软件也提升了详细设计的质量，减少相关施工变更问题，提升工程公司核心竞争力。</p>
<h3 data-tool="mdnice编辑器"><span class="js_darkmode__16">三维管道设计软件 PipeCAD</span></h3>
<p class="js_darkmode__17" data-tool="mdnice编辑器">如果说PlantAssistant是用来验证几何建模和显示性能，IsoAlgo用来生成管道轴测图，AutoDraft用来生成管道平面布置图等，那么三维管道设计软件PipeCAD则是这些能力的集成，也可以解决工厂管道数据生成问题。PipeCAD以项目数据库为核心，将工厂设计信息全部保存到数据库中，可以为图纸自动生成、材料报表等提供数据源头，也为工厂数字化交付提供数据源头。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101006973-985656877.png" alt="image" /></section>
<p class="js_darkmode__18" data-tool="mdnice编辑器">PipeCAD独立的图形平台，不依赖第三方CAD软件。支持二次开发，方便实现用户个性化需求。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101016343-73820605.png" alt="image" /></section>
<p class="js_darkmode__19" data-tool="mdnice编辑器">自研的管道轴测图生成引擎IsoAlgo，兼容ISOGEN的图形符号，提供丰富的配置选项，满足不同出图风格要求：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101026701-1468059043.png" alt="image" /></section>
<p class="js_darkmode__20" data-tool="mdnice编辑器">参数化部件库，管道等级驱动建模，提高设计效率和减少错误：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101033184-524484863.png" alt="image" /></section>
<p class="js_darkmode__21" data-tool="mdnice编辑器">支持设备、结构、梯子平台等建模：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101040453-435778768.png" alt="image" /></section>
<p class="js_darkmode__22" data-tool="mdnice编辑器">PipeCAD可以快速复用PDMS/E3D的数据，熟悉PDMS的用户可以快速上手进行设计。</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101051338-1775352601.png" alt="image" /></section>
<p class="js_darkmode__23" data-tool="mdnice编辑器">PipeCAD依然在开发迭代中，个人版免费使用。欢迎加入QQ交流群 964851855，进行技术交流、问题反馈、建议等：</p>
<section><img src="https://img2024.cnblogs.com/blog/534255/202510/534255-20251017101058443-359405766.png" alt="image" /></section>
<h2 data-tool="mdnice编辑器">&nbsp;</h2><img src ="http://www.cppblog.com/eryar/aggbug/230473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2025-10-20 10:59 <a href="http://www.cppblog.com/eryar/archive/2025/10/20/TUHE_TECH.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE HLR 轮廓线</title><link>http://www.cppblog.com/eryar/archive/2023/12/03/occt_hlr_contour_ana.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sun, 03 Dec 2023 12:53:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/03/occt_hlr_contour_ana.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230218.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/03/occt_hlr_contour_ana.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230218.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230218.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;">OpenCASCADE HLR Quadric Surface Outline Edge</h1>
<p>Key Words: HLR, Outline Edge, Sihouette Edge</p>
<h2>1 Introduction</h2>
<p>OpenCASCADE中关于隐藏线消除HLR算法的描述就是一句话：These algorithms are based on the principle of comparing each edge of the shape to be visualized with each of its faces, and calculating the visible and the hidden parts of each edge. 即根据面判断每条边Edge的遮挡关系，计算出边Edge可见和不可见部分。所以HLR算法的输入主要为边和面，计算遮挡关系依赖线面求交算法。对于精确的HLR算法依赖精确的线面求交算法，PolyAlgo算法依赖多段线与网格求交算法。输入的边中除了BREP中的边以外，还有一类是根据投影方向计算得来的，即外轮廓线Outline，也称为Contour线。ACIS的PHLR中称轮廓线Sihouette Edge。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204423504-1679258260.png" alt="" /></p>
<p>轮廓线的计算是HLR中比较关键的一步，本文以OpenCASCADE中简单的二次曲面的轮廓线计算入手来理解曲面的轮廓线概念，为理解任意曲面轮廓线计算打下基础。</p>
<h2>2 Outline Builder</h2>
<p>OpenCASCADE的HLR中使用类HLRTopoBRep_OutLiner来计算外轮廓线。轮廓线的计算依赖投影方向及投影方式，主要计算逻辑在函数Fill()中：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204440944-1736661418.png" alt="" /></p>
<p>投影方式主要分为透视投影Perspective和平行投影，工程图生成一般使用平行投影方式。实际计算类是Contap_Contour，在类Contap_Contour中又根据投影曲面类型分为两种类型来处理：</p>
<ul>
<li>二次曲面</li>
<li>任意曲面</li>
</ul>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204448284-503267688.png" alt="" /></p>
<p>其中函数PerformAna()为计算平面、球面、圆柱面、圆锥面的外轮廓线，最终会使用类Contap_ContAna。其中Ana为Analytical解析曲面的意思，这里指能用解析表达式表示的二次曲面。</p>
<h2>3 Contap_ContAna</h2>
<p>类Contap_ContAna能计算球面、圆柱面和圆锥面的外轮廓线Contour，下面我们主要来看看这三类面的外轮廓线计算结果。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204520587-275740948.png" alt="" /></p>
<p>对于平行投影球面会生成以投影方向为法向，以球半径为半径的一个圆，代码如下所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204533447-647385516.png" alt="" /></p>
<p>如下图所示中的绿色的线：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204542473-1297893842.png" alt="" /></p>
<p>对于平行投影圆柱面会生成两条直线，若投影方向与圆柱面法向平行时不生成轮廓线，这时就是使用圆柱体中的上下两个圆的边。代码如下所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204549730-207895601.png" alt="" /></p>
<p>生成的两条直线方向为圆柱面的轴方向：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231203204557306-1576414130.png" alt="" /></p>
<p>圆锥面的轮廓线生成函数逻辑类似，留给读者自行分析理解。</p>
<h2>4 Conclusion</h2>
<p>综上所述，BREP的HLR算法需要计算模型的外轮廓线。如球体的BREP边有两个退化边（极点），及两个重合边，若来投影实质上只有重合边中的一条边有用，而这个边还是个半圆。从理解 简单的二次曲面外轮廓线计算函数入手，再去深入理解任意曲面的外轮廓线计算方法。</p>
<p>理解HLR实现原理，可以重构HLR代码，也可以完全自己动手，开发出满足实际需求的自动出图程序，自动出图是工程类设计软件中相对核心的功能，目前国内基于PDMS做自动出图相关软件开发的就有很多家。本着开放的心态分享这些相对比较关键功能的原理，让国内这些产品能摆脱基于AutoCAD/BricsCAD开发接口或PDMS Draft的限制，开发出更好用、更自由灵活的软件。</p><img src ="http://www.cppblog.com/eryar/aggbug/230218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-03 20:53 <a href="http://www.cppblog.com/eryar/archive/2023/12/03/occt_hlr_contour_ana.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE-HLR Edge</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_hlr_edges.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_hlr_edges.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230217.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_hlr_edges.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230217.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230217.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE-HLR Edge</strong></h1>
<h2 style="text-align: left;">1 Introduction</h2>
<p>用计算机生成三维物体的真实图形，是计算机图形学研究的重要内容。真实图形在仿真模拟、几何造型、广告影视和科学计算可视化等许多领域都有着广泛应用。在用显示设备描述物体的图形时，必须把三维信息经过某种投影变换在二维的显示平面上绘制出来。从三维投影到二维的降维操作，会导致图形的二义性。要消除这类二义性，就必须在绘制时消除被遮挡的不可见的线或面，习惯上称之为消除隐藏线Hidden Line Removal和隐藏面Hidden Face Removal。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231202114645317-1936571585.png" alt="" /></p>
<p>这是渲染显示上对消隐的需求，在根据三维模型自动生成工程图的工程设计软件中，对消隐的需求有所不同。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231202114655229-1942560946.png" alt="" /></p>
<p>工程设计软件与机械设计软件不同，工程设计软件一次出图消隐的模型量大，对出图的算法要求主要有：</p>
<ul>
<li>主要使用消隐线算法；</li>
<li>消隐得到的线能找到与三维模型的关系，方便标注模型信息，如模型名称、规格等；</li>
<li>自动标注布局算法，能对标注的名称、规格等自动布局，减少手工调整；</li>
<li>自动尺寸标注；</li>
<li>符号化处理，如管道模型能用一条线符号化处理；</li>
</ul>
<p>其实最后总结成一句话就是一键根据模型生成能交付的图纸。虽然现在技术上具备三维模型下车间的能力，但是目前二维图纸依然是设计交付、加工制造主要依据。工程类设计软件主要的功能就是快速建模，碰撞检测和自动图纸生成。当模型量大时，消隐速度快及自动生成的标注文字排列整齐（或满足工程习惯）成了二维图纸自动生成的核心技术，也是程序处理中的难点。</p>
<h2>2 HLR</h2>
<p>几何内核一般都提供HLR算法，用来根据模型投影生成二维工程图。OpenCASCADE的HLR提供了隐藏线消隐算法。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231202114708483-1108243475.png" alt="" /></p>
<p>https://www.spatial.com/zh/products/cgm-hlr-hidden-line-removal</p>
<p>OpenCASCADE 提供了两种消隐算法：HLRBRep_Algo和HLRBRep_PolyAlgo。这些算法都是基于相同的原理：比较形状每条边相对每个面的可见性，并 计算每条边的可见部分与消隐部分。算法通过计算在指定投影方向上的物体显示特性，去除或标记被面遮挡的边。这两个算法也与一些提取功能配合使用，如重构一 个简化的模型等，简化后新的模型由边组成，就是在投影方向上的轮廓线。</p>
<h2>3 边的分类</h2>
<p>OpenCASCADE的HLR中将边分为以下类型：</p>
<ul>
<li>Sharp Edges</li>
<li>Smooth Edges</li>
<li>Sewn Edges</li>
<li>Outline Edges</li>
<li>Isoparameter Edges</li>
</ul>
<p>从类HLRBRep_HLRToShape和类HLRBRep_PolyHLRToShape中给出了这些边的一些定义。其中Sharp Edge表示C0连续（非G1连续）的边，就是一般Edge；</p>
<p>Smooth Edge表示G1连续（非G2 连续）的边；</p>
<p>Sewn Edge表示G2连续的边；</p>
<p>Outline Edge表示模型的轮廓边，这种类型的边不在BREP数据中，需要根据投影方向生成；</p>
<p>Isoparameter Edge表示面的等参线生成的边，这种类型的边不也不在BREP数据中；</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202312/534255-20231202114734232-65562309.png" alt="" /></p>
<p>其中Sharp Edge、Smooth Edge和Sewn Edge一般都是BREP中的EDGE数据，而Outline Edge和Isoparameter Edge是根据设置额外生成的边。理解边的这些定义，方便对HLR算法进行理解。HLR算法是相对简单的算法，主要是就将上述五种类型的边与面进行求交，判断遮挡关系。</p>
<p>目前OpenCASCADE中的HLR算法代码写得有点乱，上次在深圳ogg的俄罗斯开发人员提到要重构HLR部分的代码。深入理解 HLR算法，为自动生成图纸功能打下基础。</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:23 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_hlr_edges.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE 线面求交</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_intcs.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_intcs.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230216.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_intcs.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230216.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;">OpenCASCADE 线面求交</h1>
<p style="text-align: center;">eryar@163.com</p>
<h2>1 Introduction</h2>
<p>OpenCASCADE中几何曲线与曲面求交使用类GeomAPI_IntCS，是对类IntCurveSurface_HInter的简单封装。在IntCurveSurface_HInter中对曲线和曲面求交分为以下几种类型：</p>
<ul>
<li>PerformConicSurf：二次曲线与曲面求交，其中又分为两类：二次曲线与二次曲面求交和二次曲线和自由曲面求交；</li>
<li>InternalPerformCurveQuadric：自由曲线与二次曲面求交；</li>
<li>InternalPerform：自由曲线和自由曲面求交；</li>
</ul>
<p>本文主要介绍曲线与曲面求交的实现原理。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203020991-1269188047.png" alt="" /></p>
<h2>2 二次曲线与二次曲面求交</h2>
<p>二次曲线与二次曲面求交使用IntAna_ConicQuad计算，主要思路是将曲线用参数方程表示，代入二次曲面的代数方程。二次曲面可以使用二次多项式表示，将二次曲线与二次曲面相交表示成一个多项式方程，使用math_DirectPolynomialRoots对多项式方程进行求解。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203040239-785246703.png" alt="" /></p>
<h2>3 二次曲线与自由曲面求交</h2>
<p>二次曲线与自由曲面求交将曲面使用IntCurveSurface_Polyhedron在U，V上采样离散得到grid网格。这个类实现与IntPolyh_MaillageAffinage类功能有重复。</p>
<p>IntCurveSurface_ThePolygon多段线与Intf_InterferencePolygonPolyhedron 网格求交，根据多段线与网格求交情况，找到初始值，使用IntImp_IntCS计算精确值。与曲面求交的Marching算法类似，使用迭代法去计算精确交点。迭代方程为IntImp_ZerCSParFunc，写出这个方程的Value()值计算和Derivatives()微分计算公式。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203114981-549642634.png" alt="" /></p>
<p>将曲线与曲面求交问题转化为求曲面参数u,v和曲线参数w，使曲线C(w)曲面S(u,v)上的点重合，建立函数如下：</p>
<p>F(u,v,w)=S(u,v) - C(w)</p>
<p>所求的精确交点满足方程F(u,v,w)=0，F为一含有三个坐标的矢量，对应函数Value()：</p>
<p>Fx(u,v,w)=Sx(u,v) - Cx(w) = 0</p>
<p>Fy(u,v,w)=Sy(u,v) - Cy(w) = 0</p>
<p>Fz(u,v,w)=Sz(u,v) - Cz(w) = 0</p>
<p>上面为含有三个方程的以u,v,w为变量的非线性方程组，精确交点就是非线性方程组的解。使用类math_FunctionSetRoot应用Newton-Raphson迭代法求解非线性方程组的解。使用Newton迭代法有个前提条件是要求非线性方程组一阶可导，即要写出Jacobian迭代矩阵，即上述函数Derivatives()的实现原理：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203248821-1999638872.png" alt="" /></p>
<h2>4 自由曲线与二次曲面求交</h2>
<p>自由曲线与二次曲面求交IntCurveSurface_TheQuadCurvExactInter ，通过类IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter建立二次曲面与曲线之间的函数，是求解曲线上参数U的一元函数。</p>
<h2>5 自由曲线与自由曲面求交</h2>
<p>自由曲线与自由曲面求交和二维自由曲线求交类似，采用的离散法。即将曲线通过采样离散成多段线Polygon，将曲面采样生成网格Polyhedron，通过类IntCurveSurface_TheInterferenceOfHInter来计算多段线与网格的相交。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203305755-1176650810.png" alt="" /></p>
<p>包Intf主要用来计算二维多段线、三维多段线及网格的相交。根据离散计算的粗交点，再根据类IntCurveSurface_TheExactHInter使用迭代法求得精确交点。这个思想与曲面和曲面求交相同。</p>
<h2>6 求交结果</h2>
<p>曲线与曲面求交的结果主要也是保存在类IntCurveSurface_Intersection对象中，这个类的设计与二维曲线求交类似，不够直接。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231130203356660-1455224346.png" alt="" /></p>
<p>可以看到IntCurveSurface_Intersection这个类的构造函数是protected的，意思是不能直接使用，通过派生类IntCurveSurface_HInter调用SetValues()函数将求交结果保存起来。求交结果为交点IntCurveSurface_IntersectionPoint和交线IntCurveSurface_IntersectionSegment。</p>
<p>其中交点中IntCurveSurface_IntersectionPoint保存了三维坐标点，交点在曲面上的U,V参数，交点在曲线上的参数U及相交状态。交线主要是线现面和重合部分的几何奇异情况数据。</p>
<p>从类图上可以看出，这个套路同样用到了HLR算法中，理解这个套路对理解HLR算法有帮助。</p>
<h2>7 Conclusion</h2>
<p>综上所述，OpenCASCADE中将曲线与曲面求交根据曲线和曲面类型的不同分别处理。二次曲线曲面求交依赖IntAna包，自由曲线和自由曲面求交使用离散法，最终实现算法与两个曲面求交的Marching算法类似，通过离散得到的精交点，再代入迭代方程求得精确解。其中把曲线或曲面离散的采样点没有考虑曲线或曲面的曲率等，采样点数量较大，会影响性能 。曲面采样离散代码与曲面求交中的有重复。从几何求交类中可以看到没有容差的输入，可以思考一下这个问题。</p>
<p>TKGeomAlgo中除了拟合算法外，大部分代码主要就是线线求交、线面求交及面面求交算法。理解这些算法的实现原理，为Boolean算法的求交逻辑打下基础。</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:23 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_intcs.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE二维曲线求交</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_curve2d.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:22:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_curve2d.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230215.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_curve2d.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230215.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230215.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE二维曲线求交</strong></h1>
<h2>1 Introduction</h2>
<p>OpenCASCADE中对二维曲线求交和三维曲线求交是不同的，三维曲线求交统一使用离散法，二维曲线求交根据曲线类型的不同分种类型进行处理。二维曲线求交中还提供了计算自交的直接接口。在TKGeomAlgo中，主要内容就是拟合、求交算法，理解求交算法的实现原理，达到能阅读和修改源码的状态，能够分析和解决实际遇到的问题，理解OpenCASCADE的能力边界，根据需要选择所需要的功能，使软件结果可控。本文主要介绍二维曲线相交的实现原理。</p>
<p>由于OpenCASCADE开发时间相对久远，在二维曲线求交相关代码中大量使用了宏定义的方式来实现C++ 的模板template能力，宏定义在类的XXX_0.cxx文件中，对应模板实现在*.gxx中：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231127190113965-477868197.png" alt="" /></p>
<p>这种实现方式会让代码的可读性变差，不利于代码维护。应该用C++的方式对这些*.gxx代码重构，增强代码可读性和可维护性。</p>
<h2>2 求交分类</h2>
<p>二维求交使用类Geom2dAPI_InterCurveCurve， 这个类是对类Geom2dInt_GInter的封装。在类Geom2dInt_GInter中，如果只输入一条曲线，可以计算自交，如果输入两条曲线，计算两条曲线的相交。</p>
<ul>
<li>IntCurve_IntConicConic：二次曲线与二次曲线求交。二次曲线与二次曲线求交都先使用几何方法计算交点，再判断是否在参数范围内；</li>
<li>Geom2dInt_TheIntConicCurveOfGInter：二次曲线与任意曲线求交。二次曲线与任意曲线求交通过类Geom2dInt_MyImpParToolOfTheIntersectorOfTheIntConicCurveOfGInter建立距离方程，使用类math_FunctionAllRoots来对方程进行求解；</li>
<li>Geom2dInt_TheIntPCurvePCurveOfGInter：任意曲线与任意曲线求交。自由曲线求交使用离散法IntCurve_IntPolyPolyGen，使用类Geom2dInt_ThePolygon2dOfTheIntPCurvePCurveOfGInter将曲线通过采样点生成多段线Polyline，使用类Intf_InterferencePolygon2d计算多段线之间的粗交点，再使用类IntCurve_ExactIntersectionPoint通过粗交点找到曲线上的精确交点；</li>
</ul>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231127190138515-806665455.png" alt="" /></p>
<p>这些类都是从类IntRes2d_Intersection派生：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231127190147208-1703732345.png" alt="" /></p>
<p>从上图可知，二维求交结果类IntRes2d_Intersection相关派生类可知二维求交与HLR算法也有关系，理解二维曲线求交逻辑，对理解HLR代码也有帮助。</p>
<h2>3 自交计算</h2>
<p>当只输入一条曲线时，可以对曲线进行自交计算，主要实现逻辑为：若为普通二次曲线，则不会自交；若是其他曲线，使用离散法对曲线进行自交计算。代码如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231127190200122-488555626.png" alt="" /></p>
<h2>4 求交结果</h2>
<p>二维曲线求交结果保存到类IntRes2d_Intersection中，主要包含两部分：</p>
<ul>
<li>IntRes2d_IntersectionPoint：交点数据，保存交点坐标值，交点在两个曲线上的参数，及两条曲线在交点处的过渡状态Transition；</li>
<li>IntRes2d_IntersectionSegment：交线数据，当两条曲线有重叠时的几何奇异情况时，求交结果为交线；</li>
</ul>
<p>因为类IntRes2d_Interseciton的构造函数protected，所以不能直接使用这个类，都是通过其派生类使用函数SetValues()将计算得到的交点和交线数据保存起来。这里类的设计比较繁琐，代码可读性较差。</p>
<h2>5 Conclusion</h2>
<p>OpenCASCADE对于二维曲线求交进行分类处理，根据曲线类型是二次曲线、参数曲线分成三类：二次曲线与二次曲线求交、二次曲线与参数曲线求交和参数曲线与参数曲线求交，不同的求交类型采用不同的策略可以提高求交性能和稳定性。使用离散法计算二维曲线自交。从求交结果来看，也处理了几何奇异问题，即曲线重叠情况。</p>
<p>对于曲线求交还有很大改进空间：</p>
<ul>
<li>使用C++编码风格重构*.gxx代码，提高代码可读性，方便代码维护；</li>
<li>对于自由曲线求交的离散法中计算两条多段线算法中引入BVH来加速；</li>
<li>将曲线离散成多段线时考虑&#8203;曲线的曲率变化，不要均匀采样，减少多段线数量；</li>
<li>对于三维曲线求交都是使用了离散法，建议像二维曲线求交这样进行分类处理，以及引入BVH，提高性能和稳定性；</li>
</ul>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:22 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_curve2d.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE曲线上点的反求</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_extrema_pc.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:21:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_extrema_pc.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230214.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_extrema_pc.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230214.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230214.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE曲线上点的反求</strong></h1>
<p style="text-align: center;"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#114;&#121;&#97;&#114;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u>eryar@163.com</u></a></p>
<h2>1 Introduction</h2>
<p>曲线可以用代数方程表示，如圆可以用X^2+Y^2=R^2表示，也可以用参数方程X(u)=RCos(u), Y(u)=RSin(u)表示。要判断点是不是在线上，用曲线代数方程可以很直接得出结果，但是使用参数方程就没有那么直接。这也是参数曲线上点的反求问题，参数曲线上点的反求问题应用广泛，如前面所述判断点是否在曲线上、点向曲线投影、点与线的求交、点在参数曲线上的参数等，都与点的反求问题相关。本文主要结合代码介绍OpenCASCADE曲线上点的反求实现原理及使用过程中的一些注意事项。</p>
<h2>2 实现原理</h2>
<p>在《The NURBS Book》书中将点的反求问题归结为点向曲线投影距离最短的问题，如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223308624-288654811.png" alt="" /></p>
<p>建立函数f(u)=C&rsquo;(u).(C(u) - P)表示点到曲线距离，当f(u)=0时为点到曲线的最短距离，不管点P是否在曲线上。几何意义是点到曲线任意点的向量与任意点处的切向量点积为零，表示在两个向量垂直的时候求得极值点。注意数学方程中垂直这个几何意义。</p>
<p>OpenCASCADE中实现曲线上点的反求原理与《The NURBS Book》书中一致。点的反求使用类GeomLib_Tool::Parameter()函数：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223325985-1610888534.png" alt="" /></p>
<p>输入曲线、点和最大距离，计算点是否在曲线上及若在曲线上，点对应参数曲线的参数U。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223340394-1887945485.png" alt="" /></p>
<p>类Extrema_ExtPC计算点P到线C的极值Extrema。根据代码注释可以看出点的反求数学方程与《The NURBS Book》书中一致：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223354086-1220908578.png" alt="" /></p>
<p>数学方程对应的类的变量为myF，类名为Extrema_FuncExtPC，从类math_FunctionWithDerivative派生，所以必须实现两个关键虚函数Value()和Derivative()。其代码注释说明了这两个函数的实现细节：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223407926-1740284446.png" alt="" /></p>
<p>其中F(u)对应函数Value():</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223417144-1935074213.png" alt="" /></p>
<p>DF(u)对应函数Derivative()，最后使用Newton法math_FunctionRoots对方程进行求根。</p>
<h2>3 注意事项</h2>
<p>OpenCASCADE中点的反求GeomLib_Tool::Parameter()、点向曲线投影GeomAPI_ProjectPointOnCurve、点与曲线的交点IntTools_Context::ComputeVE等算法都是使用了Extrema_ExtPC类。</p>
<p>&nbsp;</p>
<p>当使用GeomLib_Tool::Parameter()函数来判断点是否在曲线上时，注意端点处点的反求要满足垂直的条件，即使点与曲线某个端点距离小于MaxDist时，也是返回false。即对于曲线端点处的情况需要自己预先处理，直接算点P与曲线端点距离与MaxDist比较，先处理端点。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223438492-2031001366.png" alt="" /></p>
<p>可以看到这里也处理的端点处的情况，但是最后没有与MaxDist有关系，最后容差是Precision::SquareConfusion()。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231121223453107-31137009.png" alt="" /></p>
<p id="1700577295832"></p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:21 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_extrema_pc.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE - 曲线自交</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_edge_self_intersect.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:21:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_edge_self_intersect.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230213.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_edge_self_intersect.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230213.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE - 曲线自交</strong></h1>
<h2>1 Introduction</h2>
<p>OpenCASCADE为二维曲线提供了求交及自交的类 Geom2dAPI_InterCurveCurve：当传入一个二维几何曲线时可以计算自交self-intersections。但是没有提供直接的三维几何曲线求交的类，也没有直接的计算自交的类。有人同学问OpenCASCADE有没有三维曲线自交的功能，其实理解两个Edge求交算法后，可以自己实现一个自交函数。</p>
<h2>2 Self-Intersection</h2>
<p>因为OpenCASCADE中两条三维曲线求交的类是IntTools_EdgeEdge，其实现原理是基于包围盒的分割法。基于这个分割递归思想，实现自交也可以参考这个思路。算法的流程为：输入一条要计算自交的边Edge，对边进行离散采样，将采样得到的每段曲线的包围盒生成BVH进行相交检测，将BVH中包围盒相交的两条曲线调用IntTools_EdgeEdge来计算相交。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231115183815260-104802493.png" alt="" /></p>
<p>离散得到的曲线段会比较多，如果用两个循环来检测两两曲线段的相交情况性能差，可以引入BVH提高性能。</p>
<h2>3 Test</h2>
<p>可以通过插值Interpolate来构造曲线测试，指定几个自交点来构造插值曲线。计算结果如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231115183832716-125622246.png" alt="" /></p>
<p>与曲线求交原理类似，都是使用离散的方法，可以思考一下数值算法如何处理。</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:21 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_edge_self_intersect.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE 曲线求交</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_edge_edge.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:20:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_edge_edge.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230212.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_edge_edge.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230212.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230212.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE 曲线求交</strong></h1>
<p style="text-align: center;"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#114;&#121;&#97;&#114;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u>eryar@163.com</u></a></p>
<h2>1 Introduction</h2>
<p>OpenCASCADE中提供了二维几何曲线的求交类Geom2dAPI_InterCurveCurve，对应到三维几何只提供了GeomAPI_IntCS, GeomAPI_IntSS，没有提供几何的GeomAPI_IntCC求交类。这些几何求交一般使用的是数值算法，即解方程。对于两条几何曲线P(u1), Q(u2)，求交就是解P(u1) - Q(u2) = 0这个方程。为什么对于三维几何曲线没有提供数值算法？</p>
<p>对于拓朴边提供了求交算法IntTools_EdgeEdge，这个类是使用类似于曲面求交的离散网格法，使用了离散包围盒法。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205207552-1984548654.png" alt="" /></p>
<p>基于包围合盒的算法是个递归算法，算法思路：</p>
<ol>
<li>1) 检查两条边在参数范围内的包围盒，若空间干涉，则进行下一步；否则退出本次判断；</li>
<li>2) 找出两条边包围盒的公共部分对应的参数，若没找到，则退出本次判断；</li>
<li>3) 并将第一条边在参数范围内分割成2或3部分，执行第一步；</li>
<li>4) 退出条件：没有相交或找到相交的参数值；</li>
</ol>
<p>第一次是分别分成2部分：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205214940-1013938627.png" alt="" /></p>
<p>在递归函数FindSolutions()中，只去对第一条边进行参数分割成3部分：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205223194-1459823810.png" alt="" /></p>
<h2>2 辅助函数</h2>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205245944-609466017.png" alt="" /></p>
<p>第一个辅助函数是FindParameters()，用来更新第二条边在第一条边的的包围盒中的参数范围，使用这个参数范围更新包围盒。</p>
<p>第二个辅助函数是CheckCoincidence()，用来检测两段边是否重合。第一步是快速计算，对边采样10个点，若通过初步粗检测，后面再深入计算。这些算法都不太高效。</p>
<p>第三个辅助函数是IsIntersection()用来判断两边条在参数范围内是否相交。</p>
<h2>3 测试</h2>
<p>将两条边求交过程中的包围盒显示出来，方便查看理解算法。先测试两个圆之间的相交：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205300955-1149046547.png" alt="" /></p>
<p>其中第一条边是绿色的圆，求交过程中的包围盒也用绿色表示；第二条边是红色的圆，求交过程中的包围盒也用红色表示。因为圆是闭合的，第一次都分割成2部分。将上面交点处理放大：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205308640-422815477.png" alt="" /></p>
<p>后面都是将第一条边分割成3部分，然后分别用这3部分的包围盒去找与第二条边相交的参数范围，再更新第二条边的包围盒。继续放大上面交点处：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205315774-595549752.png" alt="" /></p>
<p>发现对于两个圆的求交，执行了100次，效率不高。又用两个B样条曲线求交来测试：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202311/534255-20231112205323365-1135925213.png" alt="" /></p>
<p>发现对于B样条曲线求交速度较快。</p>
<h2>4 Conclusion</h2>
<p>曲线求交需要考虑重合部分，opencascae中没有使用数值算法来计算，而是采用基于包围盒的算法来处理。这种算法一般情况下可以快速找到求交解，有时递归较深，对于基本曲线可以像曲面求交一样分类处理以提高性能。opencascade中对于三维曲线求交算法性能还有优化空间。</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:20 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_int_edge_edge.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[书]-OpenCASCADE参考书籍</title><link>http://www.cppblog.com/eryar/archive/2023/12/02/occt_book.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sat, 02 Dec 2023 04:19:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/12/02/occt_book.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230210.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/12/02/occt_book.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230210.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230210.html</trackback:ping><description><![CDATA[<p>学而不思则罔，思而不学则殆。光看书籍的理论知识，没有实践看不到效果。光看occ的源码，没有理论支撑，不能抓住几何问题的本质。</p>
<p>除了在OpenCASCADE入门指南中推荐的书籍之外，还有一些进阶的书籍，放在那儿有时间就看看，总会有些收获。悟性不足，只有勤能补拙。对于看不懂的，只能用&ldquo;书读百遍，其义自见&rdquo;安慰一下自己。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202310/534255-20231030202652972-1591293169.jpg" alt="" /></p>
<p id="1698668816128">王元 数学大辞典&nbsp; 工具书&nbsp; 方便一些定义，公式，定理的查找。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202310/534255-20231030202814672-30785715.jpg" alt="" /></p>
<p id="1698668897899">《计算机辅助几何设计导论》比较全面地介绍了计算机辅助几何设计的发展历史及其主要内容和最新进展，包括现代的T样条曲线曲面。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202310/534255-20231030202949643-100965336.jpg" alt="" /></p>
<p>《样条函数与计算几何》叙述样条函数和计算几何的基本理论和方法，同时，总结了作者几年来在该领域中的研究成果.</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202310/534255-20231030203039481-1856922148.jpg" alt="" /></p>
<p id="1698669042045">《现代数学基础丛书165：散乱数据拟合的模型、方法和理论（第二版）》介绍了多元散乱数据拟合的一般方法，包括多元散乱数据多项式插值、基于三角剖分的插值方法、Boole和与Loons曲面、Sibson方法或自然邻近法、Shepard方法、Kriging方法、薄板样条方法、MQ拟插值法、径向基函数方法、运动*小二乘法、隐函数样条方法、R函数法等。同时还特别介绍了近年来国际上越来越热并在无网格微分方程数值解方面有诸多应用的径向基函数方法及其相关理论。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202310/534255-20231030203210737-959037925.jpg" alt="" /></p>
<p id="1698669133469">主要内容包括几何偏微分方程的构造方法、各种微分几何算子的离散化方法及其离散格式的收敛性、几何偏微分方程数值求解的有限差分法、有限元法以及水平集方法，还包括几何偏微分方程在曲面平滑、曲面拼接、N边洞填补、自由曲面设计、曲面重构、曲面恢复、分子曲面构造以及三维实体几何形变中的应用。</p>
<p id="1698668992693"></p>
<img src ="http://www.cppblog.com/eryar/aggbug/230210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-12-02 12:19 <a href="http://www.cppblog.com/eryar/archive/2023/12/02/occt_book.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE 扫掠曲面</title><link>http://www.cppblog.com/eryar/archive/2023/09/29/occt_sweep.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Fri, 29 Sep 2023 13:38:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/09/29/occt_sweep.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230116.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/09/29/occt_sweep.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230116.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230116.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>OpenCASCADE 扫掠曲面</strong></h1>
<p style="text-align: center;"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#114;&#121;&#97;&#114;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u>eryar@163.com</u></a></p>
<h2>1 Introduction</h2>
<p><strong>蒙皮</strong>（<strong>Skinning</strong>）就是将一簇截面曲线（section curves）融合在一起生成曲面的过程。蒙皮只是<strong>放样</strong>（<strong>Lofting</strong>）的新名词，放样可以追溯到计算机没未诞生的时候，从那时到现在，它一直在造船、汽车和航空工业中被广泛地应用。</p>
<p><strong>扫掠</strong>（<strong>Sweep</strong>）研究的是一条截面曲线沿任意路径曲线扫掠的问题。根据扫掠曲面的定义，扫掠曲面未必都能表示成NURBS形式，所以一般采用拟合算法来逼近。一种算法是基于蒙皮法，沿着路径曲线变换和采样N个截面，然后将它们作为截面曲线进行蒙皮。随着采样数量N的增加，生成的拟合曲面精度也将提高。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212453288-316905008.png" alt="" /></p>
<p>本文主要介绍OpenCASCADE中扫掠造型算法的使用，除了上面一般的扫掠曲面，还有一些高级用法。</p>
<h2>2 Sweep with Guide</h2>
<p>在DRaw Test Harness中输入命令setsweep可以看到有指定引导 线Guide的选项：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212521683-579214220.png" alt="" /></p>
<p>这个引导线Guide有什么用呢？下面给出一个示例：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212529525-408102835.png" alt="" /></p>
<p>其中Profile是扫掠截面，Spine为扫掠脊线，Guide为扫掠引导线。扫掠结果就是一个螺旋的钻头模型。在Draw Test Harness的例子中，给出两个关于引导线扫掠的示例，两个钻头：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212536763-1506916147.png" alt="" /></p>
<p>把这两个例子理解基本能掌握扫掠算法的使用方法，从这两个例子可以看出，OpenCASCADE扫掠造型能力还不错。</p>
<h2>3 Sweep on Face</h2>
<p>扫掠还有一个能力是使扫掠截面垂直于一个支撑面，这是一个有用的选项。下面还是在Draw Test Harness中测试一下：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212545567-771432609.png" alt="" /></p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929212633832-1400553507.png" alt="" /></p>
<p id="1695993995809"></p>
<p id="1695993947674"></p>
<h2>4 Conclusion</h2>
<p>OpenCASCADE中扫掠造型算法功能还比较强大，除了支持常规的扫掠外，还支持带引导线的扫掠，及带引导线的多个截面的变形扫掠，还支持截面始终垂直于支持面的扫掠选项。扫掠的关键是确定截面的变换规则，底层的蒙皮拟合算法还是比较稳定的。把Draw Test Harness中两个钻头的例子理解后，基本上应该能够掌握OpenCASCADE中扫掠造型的使用方法。</p>
<p>&nbsp;</p><img src ="http://www.cppblog.com/eryar/aggbug/230116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-09-29 21:38 <a href="http://www.cppblog.com/eryar/archive/2023/09/29/occt_sweep.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>布尔数据 面的相交</title><link>http://www.cppblog.com/eryar/archive/2023/09/29/occt_int_face.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Fri, 29 Sep 2023 10:45:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/09/29/occt_int_face.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230114.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/09/29/occt_int_face.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230114.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230114.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>布尔数据 面的相交</strong></h1>
<p style="text-align: center;"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#114;&#121;&#97;&#114;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u>eryar@163.com</u></a></p>
<h2>1 Introduction</h2>
<p>OpenCASCADE中对面的相交定义如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929181943213-511029444.png" alt="" /></p>
<p>三维空间中两个带有Geometry Surface的面Face，当两个Surface之间的距离小于Face中的容差Tolerance，则认为是相交的。一般两个面之间相交得到的是交线，还有一些情况得到的是交点，如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929181951065-128083254.png" alt="" /></p>
<p>布尔运算中面的相交是相对复杂的问题，除了考虑上述交线和交点的问题以外，还要考虑有重叠的情况；对于新生成的交线，还要考虑生成PCurve；若面上有开孔，还要将穿过开孔区域的交线排除等；最后要考虑如何保存面相交的结果。相交的计算在函数：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929181958865-1494145023.png" alt="" /></p>
<p>最终是调用IntTools_FaceFace来计算两个面的相交。并将计算结果交线和交点，是否重叠等信息保存到BOPDS_InterfFF中：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182006298-397794912.png" alt="" /></p>
<h2>2 Face Info</h2>
<p>类BOPDS_FaceInfo用来存储以下信息：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182030971-668575657.png" alt="" /></p>
<p>注意PBo31和PBSc1，一个状态是On，一个状态是Section。在相交处理类BOPAlgo_PaveFiller中通过函数BOPAlgo_PaveFiller::UpdateFaceInfo将这些相交的状态更新。</p>
<h2>3 Tangent Face</h2>
<p>从前面的文章关于检测边与边、边与面是否有重叠时采用了固定采样点来处理的不严谨的逻辑来看，判断线的重叠是个复杂的问题，判断面与面的重叠就相对更复杂。本文先从简单入手，先看对于最简单的两个平面重叠的检测，引出大家对于任意两个面重叠区域检测的思考。对这种特殊的情况处理在IntTools_FaceFace中的函数PerformPlanes()中实现。其中使用二次曲面的几何求交法进行处理，源码如下：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182100531-1354022013.png" alt="" /></p>
<p>通过源码可以看出，若两个平面之间的法向夹角小于TolAng及距离小于Tol时，则认为两个面是一样的IntAna_Same；当距离大于Tol时，则认为没有相交IntAna_Empty。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182109904-192787472.png" alt="" /></p>
<p>对于重叠的平面，将theTangentFaces设置成true表示是重叠的。这里留下一个问题大家思考：<em><strong>如何判断自由曲面的重叠情况？</strong></em></p>
<h2>4 Hole</h2>
<p>当面上有孔洞时，还要对交线进行处理，以排除掉孔洞中的交线。当使用IntTools_FaceFace来计算两个面的交线时，可以看到交线的范围不正确，没有处理孔洞情况，甚至也没有处理面的边界。如下图所示红色的交线为使用IntTools_FaceFace计算得到的：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182132177-185509352.png" alt="" /></p>
<p>当使用BOPAlgo_PaveFiller计算交线并结合PaveBlock得到交线显示如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230929182140174-31164206.png" alt="" /></p>
<p>虽然计算两个面之间的相交处理最终是调用的IntTools_FaceFace，但是要得到正确的交线需要使用类BOPAlgo_PaveFiller。这里也留下问题供大家思考：<em><strong>为什么IntTools_FaceFace计算的交线范围不正确？为什么BOPAlgo_PaveFiller计算的交线正确？</strong></em></p>
<h2>5 Conclusion</h2>
<p>综上所述，布尔数据中面的相交的结果可能有交线，也可能有交点。将求交结果保存到FaceInfo中。从简单的两个平面重叠来看，将重叠的状态用变量theTangetFaces来保存。那任意两个曲面重叠如何判断呢？面的相交虽然提供类IntTools_FaceFace来计算，但是没有正确处理交线的范围，为什么BOPAlgo_PaveFiller中可以正确处理交线呢？</p>
<p>&nbsp;</p>
<p><span style="font-size: 18px;"><strong>祝大家中秋国庆节日快乐！</strong></span></p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-09-29 18:45 <a href="http://www.cppblog.com/eryar/archive/2023/09/29/occt_int_face.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>布尔数据 边的相交</title><link>http://www.cppblog.com/eryar/archive/2023/09/27/occt_edge_int.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Wed, 27 Sep 2023 13:52:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/09/27/occt_edge_int.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230108.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/09/27/occt_edge_int.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230108.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230108.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;"><strong>布尔数据 边的相交</strong></h1>
<p style="text-align: center;"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#114;&#121;&#97;&#114;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u>eryar@163.com</u></a></p>
<h2>1 Introduction</h2>
<p>在OpenCASCADE中对于边的相交分为三类：边与点，边与边，边与面，边与点的相交已经归结为点与边的相交处理了，边的相交主要处理边与边，边与面的相交。边与边、边与面的相交会引入一个新的数据结构-公共部分Common Part，用于保存重叠的公共部分数据。</p>
<h2>2 Edge/Edge Interferences</h2>
<p>对于两条边的相交是指在两条边的某些地方的距离小于边的容差之和，主要分为两种情况，一种是两条边只有一个交点的情况；一种是有重叠部分的情况；先看只有一个交点情况：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213139399-1355704272.png" alt="" /></p>
<p>我们在DRAW中通过脚本构造最简单的情况来测试。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213148563-188888646.png" alt="" /></p>
<p>在处理边与边相交的函数BOPAlgo_PaveFiller::PerformEE()中，对每两条边调用BOPAlgo_EdgeEdge进行求交。从这里可以看到Pave Block的使用，相当于对每两条边上的每对Pave Block部分进行求交。这里有一些优化空间，目前是使用的两个循环处理，可以尝试使用BVH来提升一些性能。当每对Pave Block对应的点的索引号一致时，即每对Pave Block的端点重叠时，使用快速计算的算法来判断是否有重叠。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213207083-727333736.png" alt="" /></p>
<p>对于边的求交结果保存到BOPDS_InterfEE中，都会保存是哪两条边相交及相交的公共部分。对于相交于一点的公共部分的类型为TopAbs_VERTEX，对于有重叠部分的公共部分类型为TopAbs_EDGE：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213219455-1330844151.png" alt="" /></p>
<p>当两边条有重叠部分时，如下图所示：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213233801-157268512.png" alt="" /></p>
<p>如何检测两条边的公共部分呢？在函数IntTools_EdgeEdge::IsCoincident()中实现：</p>
<pre class="language-cpp highlighter-hljs"><code>//=======================================================================
//function :  IsCoincident
//purpose  : 
//=======================================================================
Standard_Boolean IntTools_EdgeEdge::IsCoincident() 
{
  Standard_Integer i, iCnt, aNbSeg, aNbP2;
  Standard_Real dT, aT1, aCoeff, aTresh, aD;
  Standard_Real aT11, aT12, aT21, aT22;
  GeomAPI_ProjectPointOnCurve aProjPC;
  gp_Pnt aP1;
  //
  aTresh=0.5;
  aNbSeg=23;
  myRange1.Range(aT11, aT12);
  myRange2.Range(aT21, aT22);
  //
  aProjPC.Init(myGeom2, aT21, aT22);
  //
  dT=(aT12-aT11)/aNbSeg;
  //
  iCnt=0;
  for(i=0; i &lt;= aNbSeg; ++i) {
    aT1 = aT11+i*dT;
    myGeom1-&gt;D0(aT1, aP1);
    //
    aProjPC.Perform(aP1);
    aNbP2=aProjPC.NbPoints();
    if (!aNbP2) {
      continue;
    }
    //
    aD=aProjPC.LowerDistance();
    if(aD &lt; myTol) {
      ++iCnt; 
    }
  }
  //
  aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
  return aCoeff &gt; aTresh;
}</code></pre>
<p>从上述代码可以看出，对于重叠部分的检测是将一条边根据检测范围分成23段采样点，计算每个点到另一条边的距离，满足条件的采样点的数量超过12个，基本认为是重叠的。从这里可以看出这样检测重叠稍微有点不严谨。固定采样点数量对于小段曲线来说数量过大，对于很长的曲线来说数量又偏小，这里有待提高。如果重叠，则将公共部分的数据保存起来：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213307293-1447779286.png" alt="" /></p>
<p>对于测试的TCL脚本不会走这个通用的判断流程，会直接有IntTools_EdgeEdge::ComputeLineLine()函数来处理这种特殊情况：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213326878-437572611.png" alt="" /></p>
<p>从保存的数据可以看出，公共部分的相交类型为TopAbs_VERTEX，及交点分别在两条边上的参数。关于有重叠部分的两条边相交，同学们可以自行使用DRAW脚本来测试一下。</p>
<h2>3 Edge/Face Interferences</h2>
<p>边与面的相交会遇到和边与边相交类似的情况，即会有重叠部分Common Part。也分为两种情况，一种情况是边与面只有一个交点的情况，交点可能会有多个；一种情况是有重叠部分的情况。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213344767-964332040.png" alt="" /></p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213352751-1688721007.png" alt="" /></p>
<p id="1695821627053"></p>
<p>我们可以在使用脚本来测试一下重叠的情况：</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230927213408342-243270677.png" alt="" /></p>
<p>从代码中可以看出当边的端点在面上时，则会判断边与面会不会重叠Coincidence。判断逻辑与判断边是否重叠类似，都是使用固定23个采样点的方式处理，并加上定位器来判断点是否在面上，因为面上可能会有孔洞：</p>
<pre class="language-cpp highlighter-hljs"><code>//=======================================================================
//function :  IsCoincident
//purpose  : 
//=======================================================================
Standard_Boolean IntTools_EdgeFace::IsCoincident() 
{
  Standard_Integer i, iCnt;
  Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
  gp_Pnt aP;
  TopAbs_State aState;
  gp_Pnt2d aP2d;
  //
  GeomAPI_ProjectPointOnSurf&amp; aProjector=myContext-&gt;ProjPS(myFace);
  Standard_Integer aNbSeg=23;
  if (myC.GetType() == GeomAbs_Line &amp;&amp;
      myS.GetType() == GeomAbs_Plane)
    aNbSeg = 2; // Check only three points for Line/Plane intersection
  const Standard_Real aTresh = 0.5;
  const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
                         aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
  const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
  aT1=myRange.First();
  aT2=myRange.Last();
  Standard_Real aBndShift = 0.01 * (aT2 - aT1);
  //Shifting first and last curve points in order to avoid projection
  //on surface boundary and rejection projection point with minimal distance
  aT1 += aBndShift;
  aT2 -= aBndShift;
  dT=(aT2-aT1)/aNbSeg;
  //
  Standard_Boolean isClassified = Standard_False;
  iCnt=0;
  for(i=0; i &lt;= aNbSeg; ++i) {
    aT = aT1+i*dT;
    aP=myC.Value(aT);
    //
    aProjector.Perform(aP);
    if (!aProjector.IsDone()) {
      continue;
    }
    //
    aD=aProjector.LowerDistance();
    if (aD &gt; myCriteria) {
      if (aD &gt; 100. * myCriteria)
        return Standard_False;
      else
        continue;
    }
    //
    ++iCnt; 
    //We classify only three points: in the begin, in the 
    //end and in the middle of the edge.
    //However, exact middle point (when i == (aNbSeg + 1)/2)
    //can be unprojectable. Therefore, it will not be able to
    //be classified. Therefore, points with indexes in 
    //[aTreshIdxF, aTreshIdxL] range are made available 
    //for classification.
    //isClassified == TRUE if MIDDLE point has been chosen and
    //classified correctly.
    if(((0 &lt; i) &amp;&amp; (i &lt; aTreshIdxF)) || ((aTreshIdxL &lt; i ) &amp;&amp; (i &lt; aNbSeg)))
      continue;
    if(isClassified &amp;&amp; (i != aNbSeg))
      continue;
    aProjector.LowerDistanceParameters(aU, aV);
    aP2d.SetX(aU);
    aP2d.SetY(aV);
    IntTools_FClass2d&amp; aClass2d=myContext-&gt;FClass2d(myFace);
    aState = aClass2d.Perform(aP2d);
    if(aState == TopAbs_OUT)
      return Standard_False;
    if(i != 0)
      isClassified = Standard_True;
  }
  //
  const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
  return (aCoeff &gt; aTresh);
}</code></pre>
<p>求交结果与边与边相交类型，会保存边与面的索引，及公共部分的数据。除了保存这些数据以外，还和点与面相交一样，更新面上的信息FaceInfo，即有哪些边在面上。</p>
<h2>4 Conclusion</h2>
<p>综上所述，边与边、边与面相交会得到公共部分Common Part，公共部分可能是点，也可能是重叠的边。在过滤相交的边与边、边与面时都有一定的优化空间，即使用BVH来加速检测相交部分。在快速判断边与边是否重叠、边与面是否重叠部分的代码采用固定数量的采样点的处理方式不太严谨。将相交的结果及过程数据都保存到BOPDS_DS中作为后面算法使用。</p>
<img src ="http://www.cppblog.com/eryar/aggbug/230108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-09-27 21:52 <a href="http://www.cppblog.com/eryar/archive/2023/09/27/occt_edge_int.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[开源]-OpenCASCADE-IMGUI</title><link>http://www.cppblog.com/eryar/archive/2023/09/24/occt_imgui_glfw.html</link><dc:creator>eryar</dc:creator><author>eryar</author><pubDate>Sun, 24 Sep 2023 11:33:00 GMT</pubDate><guid>http://www.cppblog.com/eryar/archive/2023/09/24/occt_imgui_glfw.html</guid><wfw:comment>http://www.cppblog.com/eryar/comments/230102.html</wfw:comment><comments>http://www.cppblog.com/eryar/archive/2023/09/24/occt_imgui_glfw.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/eryar/comments/commentRss/230102.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/eryar/services/trackbacks/230102.html</trackback:ping><description><![CDATA[<h1 style="text-align: center;">[开源]-OpenCASCADE-IMGUI</h1>
<h2>1 IMGUI</h2>
<p>ImGui 是一个用于C++的用户界面库，跨平台、无依赖，支持OpenGL、DirectX等多种渲染API，是一种即时UI（Immediate Mode User Interface）库，保留模式与即时模式的区别参考<a href="https://learn.microsoft.com/zh-cn/windows/win32/learnwin32/retained-mode-versus-immediate-mode" target="_blank" rel="noopener"><strong>保留模式与即时模式</strong></a>。ImGui渲染非常快，但界面上有大量的数据集需要渲染可能会有一些问题，需要使用一些缓存技巧。缓存只是避免数据的更新逻辑耗时太久影响渲染，实际渲染过程不存在瓶颈。</p>
<p>IMGUI很轻量，还支持跨平台，对于小的测试程序IMGUI是理想的GUI。</p>
<h2>2 OcctImgui</h2>
<p>基于opencascade的glfw sample加入IMGUI，这样就可以开发一些带有GUI的程序。这些程序小巧且能方便跨平台，看上去效果也不错。</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230924095848466-2038356090.png" alt="" /></p>
<p id="1695520732450">现在将OcctImgui开源，开源地址：https://github.com/eryar/OcctImgui</p>
<p>使用Premake来生成解决方案，只需要将premake5.lua中的相关第三方库的路径修改一下，即可以直接编译运行。</p>
<h2>3 Next</h2>
<p>目前occt的视图作为整个背景，下一步可以做成像CADRays中那样，将occt的视图作为视图的一部分，这样就可以使用IMGUI的Docking功能。</p>
<p>使用IMGUI也可以开发出很Cool的界面，最后放两个基于IMGUI开发的图形界面：</p>
<p>https://github.com/adriengivry/Overload</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230924100632768-2050956857.png" alt="" /></p>
<p id="1695521195784">https://github.com/sasobadovinac/CADRays</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230924100716935-1153331757.png" alt="" /></p>
<p id="1695521239424">https://github.com/MeshInspector/MeshLib</p>
<p><img src="https://img2023.cnblogs.com/blog/534255/202309/534255-20230924100821074-217645834.png" alt="" /></p>
<p id="1695521303538"></p><img src ="http://www.cppblog.com/eryar/aggbug/230102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/eryar/" target="_blank">eryar</a> 2023-09-24 19:33 <a href="http://www.cppblog.com/eryar/archive/2023/09/24/occt_imgui_glfw.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>