CGAL - OpenVDB网格化中的噪声
我正在尝试使用CGAL对一个OpenVDB (.vdb) 文件进行网格化。
在中等网格分辨率下,对有机形体的网格化效果很好。但特别是在尝试对高纵横比的形体进行网格化时,我输出的网格会有相当明显的噪声。起初我以为可能是体素分辨率过低导致的,但这个问题似乎并未因此而受到影响。
这个脚本是一个最小版本,用来重现这个问题(你需要CGAL和 OpenVDB的库,可能需要以release构建,至少我在调试模式下构建时遇到了困难):
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <openvdb/openvdb.h>
#include <openvdb/tools/Interpolation.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
namespace params = CGAL::parameters;
int main()
{
// --- Load VDB ---
openvdb::initialize();
openvdb::io::File file("../data/Cylinder.vdb");
file.open();
auto grid = openvdb::gridPtrCast<openvdb::FloatGrid>(
file.readGrid(file.beginName().gridName()));
file.close();
const double voxelSize = grid->transform().voxelSize()[0];
const openvdb::math::Transform& xform = grid->transform();
// --- Bounding box ---
openvdb::CoordBBox bbox = grid->evalActiveVoxelBoundingBox();
openvdb::Vec3d worldMin = xform.indexToWorld(bbox.min().asVec3d());
openvdb::Vec3d worldMax = xform.indexToWorld(bbox.max().asVec3d());
K::Iso_cuboid_3 boundingBox(
K::Point_3(worldMin[0], worldMin[1], worldMin[2]),
K::Point_3(worldMax[0], worldMax[1], worldMax[2]));
// --- Implicit domain from VDB SDF ---
auto accessor = grid->getConstAccessor();
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(
[&accessor, &xform, voxelSize](const K::Point_3& p) -> K::FT {
openvdb::Vec3d idx = xform.worldToIndex(
openvdb::Vec3d(p.x(), p.y(), p.z()));
float val = openvdb::tools::PointSampler::sample(accessor, idx);
return static_cast<K::FT>(val * voxelSize);
},
boundingBox);
// --- Mesh criteria ---
Mesh_criteria criteria(
params::facet_angle(20)
.facet_size(voxelSize * 300)
.facet_distance(voxelSize * 3)
.cell_radius_edge_ratio(2)
.cell_size(voxelSize * 300));
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
std::ofstream out("out.mesh");
CGAL::IO::write_MEDIT(out, c3t3);
return 0;
}
有人有解决方法/解释吗,或者有其他方法能够用CGAL对 .vdb文件进行网格化吗?
解决方案
尝试在命名参数 relative_error_bound 中放入更好的近似。
* \cgalNamedParamsBegin
* \cgalParamNBegin{relative_error_bound}
* \cgalParamDescription{the relative error bound used to compute intersection points between the implicit surface and query segments.
* The bisection is stopped when the length of the intersected segment is less than the product
* of `relative_error_bound` by the diameter of the bounding object.}
* \cgalParamDefault{FT(1e-3)}
* \cgalParamNEnd
* \cgalNamedParamsEnd
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。