首页 > 其他分享 ># 代码实践篇四 如何切割曲面或求平面与曲面的交?

# 代码实践篇四 如何切割曲面或求平面与曲面的交?

时间:2024-07-19 16:26:11浏览次数:12  
标签:std 或求 切割 slicer CGAL mesh 曲面 Mesh include

代码实践篇四 如何切割曲面或求平面与曲面的交?

简述思路

借助CGAL几何库,分为以下步骤:

  1. 曲面为surface mesh类型,因为要polygon processing接口,其他格式可以用copy_face_graph转换;
  2. split用于分割,clip用于切割,剩余部分和clipper的方向有关;
  3. slicer用的是AABB_tree,就是射线检测那一套求plane与mesh的交点集返回polyline

问题

  1. 对于split函数,分割成多个mesh后,需要调用split_connected_components分割连通域,这么设计的原则应该是为了泛型和增加内存使用效率;
  2. params里面的参数自行查看,一般要避免自信爱干净报异常。
  3. 用split和clip用plane也是可以的。但为什么例子要用mesh?因为mesh可以即可以模仿平面的范围,也可以用于非平面的结构。

接口原型

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>

#include <CGAL/Vector_3.h>
#include <CGAL/Surface_mesh.h>

//clip和split
#include <CGAL/Polygon_mesh_processing/clip.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>


//slicer
#include <CGAL/AABB_halfedge_graph_segment_primitive.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
 
#include <CGAL/Polygon_mesh_slicer.h>
 
//CGAL里面求交后优化的核心模块
 #include <CGAL/Polygon_mesh_processing/corefinement.h>
#include <CGAL\Polygon_mesh_processing\internal\Corefinement\intersection_impl.h>


namespace PMP = CGAL::Polygon_mesh_processing;

using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = Kernel::Point_3;
using Vector_3 = Kernel::Vector_3;
using Plane_3 = Kernel::Plane_3;
using Mesh = CGAL::Surface_mesh<Kernel::Point_3>;

using Polyline3D = std::vector<Point_3>;
using Polyline3Ds = std::vector<Polyline3D>;
 
typedef CGAL::AABB_halfedge_graph_segment_primitive<Mesh> HGSP;
typedef CGAL::AABB_traits<Kernel, HGSP>    AABB_traits;
typedef CGAL::AABB_tree<AABB_traits>  AABB_tree;

bool ClipMesh(Mesh& mesh, Mesh& clippermesh);
bool SplitMesh(Mesh& mesh, Mesh& splittermesh,std::vector<Mesh>& AfterSplitterComponents);
void SlicerMesh(Mesh& mesh, Plane_3& SlicerPlane,Polyline3Ds& IntersectionRegions);

代码

bool ClipMesh(Mesh& mesh, Mesh& clippermesh)
{
    
    bool clipresult = false;
    try
    {
        //allow_self_intersections一般设为false,通过捕捉异常处理
        //clip实质调用的是corefinement里面的函数
        clipresult = PMP::clip(mesh, clippermesh, CGAL::parameters::use_compact_clipper(true).allow_self_intersections(true));
        
    }
    catch (const std::exception& e)
    {
        //自行处理异常,一般异常是自相交共面退化引起的
        std::cout << "clip error: " << e.what() << std::endl;
        
    }
    return clipresult;
}
bool SplitMesh(Mesh& mesh, Mesh& splittermesh,std::vector<Mesh>& AfterSplitterComponents)
{
     namespace params = CGAL::parameters;
     bool splitresult = true;
    try
    {
        //throw_on_self_intersection是为了避免报异常,因为自相交太常见
        //do_not_modify是为了减少splittermesh的修改,这个参数应该是Corefinement里面为了减少诸如splitter和clipper修改的,但是不是所有接口都更新好了。
        PMP::split(mesh, splittermesh,params::throw_on_self_intersection(false),
        params::do_not_modify(false));

        PMP::split_connected_components(mesh, AfterSplitterComponents, params::default_values());

    }
    catch (const std::exception& e)
    {
        //自行处理异常,一般异常是自相交共面退化引起的
        std::cout << "split error: " << e.what() << std::endl;
        splitresult = false;
    }
    return splitresult;
    
    
}

void SlicerMesh(Mesh& mesh, Plane_3& SlicerPlane,Polyline3Ds& IntersectionRegions)
{
    //简单构造
    CGAL::Polygon_mesh_slicer<Mesh, Kernel> slicer(mesh);
    slicer(SlicerPlane, std::back_inserter(IntersectionRegions));
    IntersectionRegions.clear();

    //利用AABB_tree加速处理用于多次频繁操作
     AABB_tree tree(edges(mesh).first, edges(mesh).second, mesh);
    CGAL::Polygon_mesh_slicer<Mesh, Kernel> slicer_aabb(mesh, tree);
    slicer_aabb(SlicerPlane, std::back_inserter(IntersectionRegions));
    std::cout << "the slicer intersects "
            << IntersectionRegions.size() << " IntersectionRegions" << std::endl;
    IntersectionRegions.clear();

}

##结果
在这里插入图片描述

标签:std,或求,切割,slicer,CGAL,mesh,曲面,Mesh,include
From: https://blog.csdn.net/weixin_44677002/article/details/140552574

相关文章

  • LogRotate 切割 Nginx 日志
     发布于 2023-12-0410:20:327140举报文章被收录于专栏:码农UP2U一直以来做日志切割都是使用shell+crontab来搞,shell脚本可以在网上找到各种版本的,改改就用了,懒省事。这样的做法很传统,却忽略了系统的给我们提供的优秀的工具——logrotate。......
  • logging模块切割日志时:另一个程序正在使用此文件,进程无法访问。
    使用:  concurrent-log-handlerGITHUB:  https://github.com/Preston-Landers/concurrent-log-handler安装: pipinstallconcurrent-log-handlerimportloggingfromconcurrent_log_handlerimportConcurrentRotatingFileHandlerlogger=logging.getLogger(__name_......
  • 几何建模基础-样条曲线和样条曲面介绍
    1.概念介绍1.1样条曲线的来源样条的英语单词spline来源于可变形的样条工具,那是一种在造船和工程制图时用来画出光滑形状的工具:富有弹性的均匀细木条/金属条/有机玻璃条,它围绕着按指定位置放置的重物或者压铁做弹性弯曲,以获得所需要的曲线,如下图所示。在计算机科学的计算机辅......
  • 打卡信奥刷题(267)用Scratch图形化工具信奥P10415 [普及组][蓝桥杯 2023 国 A] 切割
    [蓝桥杯2023国A]切割题目描述给定一个W×HW\timesHW×H的长方形,两边长度均为整数。小蓝想把它切割为......
  • CAN转PN网关模块连接激光切割机的配置方法
    激光切割机在工业生产中被广泛应用,而激光发射器与控制设备常以不同的协议存在两者之间,CAN总线和Profinet以各自的特点被广泛用于设备当中。本文将介绍介绍兴达易控CAN转Profinet网关模块(XD-PN_CAN20)连接CAN激光切割机的使用方法。一、功能及优势CAN转Profinet网关模块(XD-PN_C......
  • go中实现日志级别与切割,日志配置热生效,pprof的技术解析
    引言在线上分布式系统和微服务架构中,日志记录是排查问题、调试程序和监控服务运行状态的重要手段。合理设置日志级别,可以帮助开发和运维人员有效地获取所需信息。然而,在实际运行中,常常需要在不重启服务的情况下动态调整日志级别,以适应不同的调试需求和运行环境。本文基于g......
  • Bezier曲线曲面--拟合技术
    Bezier曲线曲面–拟合应用1.Bezier曲线1.1.Bezier曲线的定义给定一组控制点P_0,P_1,…,P_n,其中n是曲线的阶数,Bezier曲线的参数方程可以表示为:B(t......
  • (转)Linux环境下使用logrotate工具实现nginx日志切割
    原文:https://www.cnblogs.com/even160941/p/13903291.html一.前提背景及需求Nginx运行日志默认保存在Nginx安装目录下的 /usr/local/nginx/logs目录(或/var/log/nginx目录下),包含access.log和error.log两个文件。(1) access.log 记录了哪些用户、哪些页面以及用户浏览器、i......
  • 大厂笔试真题讲解—美团23—小美的蛋糕切割
     本题主要讲解小美的蛋糕切割的要点和细节,根据步骤一步步思考易于理解提供c++的核心代码以及acm模式代码,末尾题目描述小美有一个矩形的蛋糕,共分成了n行m列,共n*m个区域,每个区域是一个小正方形,已知蛋糕每个区域都有一个美味度。她想切一刀把蛋糕切成两部分,自己吃一......
  • 【JavaScript】内置对象 - 字符串对象 ⑦ ( String 字符串替换 | replace 函数 | repl
    文章目录一、String字符串替换1、replace函数替换字符串2、使用replace函数替换所有匹配字符串3、replaceAll函数替换字符串二、String字符串转数组1、split函数切割字符串2、代码示例-切割字符串String字符串对象参考文档:https://developer.mozilla.......