You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用CGAL对两个非流形模型执行布尔运算?

How to Perform Boolean Operations on Non-Manifold Models with CGAL

Hey Martin, let's break this down clearly—CGAL's Polygon Mesh Processing (PMP) and Nef_Polyhedron boolean tools require closed, manifold, non-self-intersecting meshes to work reliably. Non-manifold geometry (like edges shared by 3+ faces, isolated vertices/edges, or non-2-manifold vertices) will almost always cause these operations to fail. Here's a step-by-step solution tailored to your .stl→.off→Polyhedron workflow:

Step 1: Repair the Non-Manifold Mesh First

Before even thinking about boolean operations, you need to convert your non-manifold mesh into a valid manifold structure. CGAL has built-in tools for this, plus manual fixes for trickier cases:

Option 1: Automated Mesh Repair with CGAL

Use CGAL::Polygon_mesh_processing::repair_polygon_mesh() to fix common non-manifold issues like isolated vertices, duplicate vertices, and small cracks. Here's a quick code snippet:

#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polyhedron_3.h>
#include <fstream>

typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;

int main() {
  std::ifstream input("your_model.off");
  Polyhedron mesh;
  input >> mesh;

  // Attempt automated repair
  bool repair_success = CGAL::Polygon_mesh_processing::repair_polygon_mesh(mesh);

  std::ofstream output("repaired_model.off");
  output << mesh;
  return 0;
}

Note: This tool can't fix all non-manifold cases (e.g., edges shared by 3+ faces). If it fails, you'll need to manually address those elements.

Option 2: Manual Fixes for Complex Non-Manifold Geometry

For edges shared by more than 2 faces (a common non-manifold issue), you can split edges or remove redundant faces to restore manifoldness. Use CGAL's iterators to identify and fix these:

// Iterate over all edges to find non-manifold ones
for (auto e = mesh.edges_begin(); e != mesh.edges_end(); ++e) {
  int face_count = 0;
  auto h = e->halfedge();
  do {
    if (!h->is_border()) face_count++;
    h = h->opposite()->next();
  } while (h != e->halfedge());

  // If edge is shared by >2 faces, split it
  if (face_count > 2) {
    CGAL::split_edge(*e);
  }
}

Step 2: Validate the Repaired Mesh

Once you've repaired the mesh, confirm it meets CGAL's boolean operation requirements with these checks:

#include <CGAL/Polygon_mesh_processing/manifoldness.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>

// ... Load your repaired mesh ...

bool is_closed = CGAL::Polygon_mesh_processing::is_closed(mesh);
bool is_manifold = CGAL::Polygon_mesh_processing::is_manifold(mesh);
bool has_self_intersections = CGAL::Polygon_mesh_processing::does_self_intersect(mesh);

std::cout << "Closed: " << is_closed << "\nManifold: " << is_manifold << "\nSelf-intersections: " << has_self_intersections << std::endl;

All three should return true before proceeding to boolean operations. If self-intersections exist, use CGAL::Polygon_mesh_processing::self_intersections() to locate and fix them.

Step 3: Execute Boolean Operations

With a valid manifold mesh, you can use either PMP or Nef_Polyhedron for boolean operations:

Using Polygon Mesh Processing (Best for Triangle Meshes)

If your converted .off mesh is made of triangles (most .stl files are), use PMP's corefinement tools for unions, intersections, or differences:

#include <CGAL/Polygon_mesh_processing/corefinement.h>

// Assume mesh1 and mesh2 are repaired, valid meshes
Polyhedron union_result;
bool bool_success = CGAL::Polygon_mesh_processing::corefine_and_compute_union(
  mesh1, mesh2, union_result,
  CGAL::parameters::vertex_point_map(get(CGAL::vertex_point, mesh1))
                   .vertex_point_map(get(CGAL::vertex_point, mesh2)));

if (bool_success) {
  std::ofstream out("union_result.off");
  out << union_result;
}

Replace corefine_and_compute_union with corefine_and_compute_intersection or corefine_and_compute_difference as needed.

Using Nef_Polyhedron (For More Complex Topologies)

Nef polyhedra support advanced boolean operations, but you first need to convert your valid Polyhedron to a Nef_polyhedron_3:

#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Nef_polyhedron_iostream_3.h>

typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;

// Convert valid Polyhedra to Nef polyhedra
Nef_polyhedron nef1(mesh1);
Nef_polyhedron nef2(mesh2);

// Perform boolean operations
Nef_polyhedron union_nef = nef1 + nef2;
Nef_polyhedron intersect_nef = nef1 * nef2;
Nef_polyhedron difference_nef = nef1 - nef2;

// Convert back to Polyhedron if needed
Polyhedron result_mesh;
union_nef.convert_to_polyhedron(result_mesh);
std::ofstream out("nef_union_result.off");
out << result_mesh;

Bonus Tip

If automated repair in CGAL isn't enough for your model's non-manifold issues, use a desktop mesh editing tool to manually fix problematic areas first—clean up non-manifold edges, fill holes, and remove self-intersections before importing back into CGAL.

内容的提问来源于stack exchange,提问作者Martin LU

火山引擎 最新活动