简述思路
借助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返回。
问题
- 挤压处理的数据结构可以自行定义,接口是给上下曲面挤压方向;
接口原型
#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);
}
}
结果
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
几何代码及文字整理
本文地址: 代码实践篇三 如何拉伸/挤压有产状曲面?
本文地址: 代码实践篇三 如何拉伸/挤压有产状曲面?
您必须 登录 才能发表评论