简述思路

借助CGAL几何库,分为以下步骤:
1. 曲面为surface mesh类型,因为要polygon processing接口,其他格式可以用copy_face_graph转换;
2. 利用oriented_bounding_box求出有向bbox,参数加上use_convex_hull=true进行优化;
3. 根据bbox求出mesh的法向量;
4. 定义挤压处理的数据结构;
5. 调用extrude_mesh返回。

问题

  1. 挤压处理的数据结构可以自行定义,接口是给上下曲面挤压方向;

接口原型

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/extrude.h>
#include <CGAL/Vector_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/optimal_bounding_box.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>;

typedef boost::property_map<Mesh, CGAL::vertex_point_t>::type  VPMap;

struct BottomNormal
{
    BottomNormal(VPMap pmap, Vector_3 normal /*VNMap nmap*/, double vlen)
        : pmap(pmap), normal(normal), vlen(vlen)
    {}
    void operator()(const vertex_descriptor& vin, const vertex_descriptor vout) const
    {
        put(pmap, vout, get(pmap, vout) - vlen * normal /*get(nmap, vin)*/);
    }
    VPMap pmap;
    Vector_3 normal;
    //VNMap nmap;
    double vlen;
};

struct TopNormal
{
    TopNormal(VPMap pmap, Vector_3 normal/*VNMap nmap*/, double vlen)
        : pmap(pmap), normal(normal), vlen(vlen)
    {}
    void operator()(const vertex_descriptor& vin, const vertex_descriptor vout) const
    {
        put(pmap, vout, get(pmap, vout) + vlen * normal/*get(nmap, vin)*/);
    }
    VPMap pmap;
    Vector_3 normal;
    //VNMap nmap;
    double vlen;
};

bool ExtrudeAttitudeMesh(Mesh& mesh, Mesh& extrudemsh,double topextrude,double downextrude);

代码

bool TriangulateByPolyline(Mesh& mesh, Mesh& extrudemsh,double topextrude,double downextrude)
{
    //求出有向bbox
    std::array<Point_3, 8> obb_points;
    CGAL::oriented_bounding_box(mesh, obb_points,
    CGAL::parameters::use_convex_hull(true));


    //三点确定一个平面
    Plane_3 plane(obb_points[0], obb_points[1], obb_points[2]);

    //求出法向量并归一化
    Vector_3 normal = plane.orthogonal_vector();

    normal /= std::sqrt(normal.squared_length());


    //挤压
    BottomNormal bottom(get(CGAL::vertex_point, extrudemsh), normal, downextrude);
    TopNormal top(get(CGAL::vertex_point, extrudemsh), normal, topextrude);
    PMP::extrude_mesh(mesh, extrudemsh, bottom, top);

    //挤压可能导致封闭的面并不都是向外的
    if (!PMP::is_outward_oriented(extrudemsh))
    {
        PMP::orient(extrudemsh);
    }
}

结果

结果

您必须 登录 才能发表评论