布尔操作(Boolean Operators)
1 构造实体几何(CSG)
构造实体几何允许建模者通过使用布尔运算符组合更简单的对象来创建复杂的曲面或对象,通过组合一些基元对象,能够生成复杂的对象。
CSG可以用二叉树表示,叶子节点表示基元,节点表示相应的操作,经典的CSG二叉树如图所示:
2 布尔操作类型
基元的布尔操作类型主要有以下几种:
类型 | 图片 |
---|---|
布尔并 | ![]() |
布尔交 | ![]() |
布尔差 | ![]() |
3 布尔操作部分代码
这边主要用到的库为cork
🔗可以在github中获取点击cork库链接
BooleanOperation代码如下:
头文件
#pragma once
#include"../trimesh/include/TriMesh.h"
#include"cork.h"
class BooleanOperation
{
public:
BooleanOperation();
~BooleanOperation();
public:
static TriMesh* mesh_boolean_union(TriMesh* mesh0, TriMesh* mesh1);
static TriMesh* mesh_boolean_intersection(TriMesh* mesh0, TriMesh* mesh1);
static TriMesh* mesh_boolean_difference(TriMesh* mesh0, TriMesh* mesh1);
static TriMesh* mesh_boolean_symmetric_difference(TriMesh* mesh0, TriMesh* mesh1);
static CorkTriMesh* TriMesh_To_CorkTriMesh(TriMesh* mesh);
static TriMesh* CorkTriMesh_To_TriMesh(CorkTriMesh* corkmesh);
static TriMesh* resolve_Intersections(TriMesh* mesh0, TriMesh* mesh1);
void OnUnion();
void OnIntersection();
void OnDifference();
void OnSymmetricDifference();
void OnResolveIntersections();
};
源文件
#include "BooleanOperation.h"
#include "../MainFrm.h"
BooleanOperation::BooleanOperation()
{
}
BooleanOperation::~BooleanOperation()
{
}
TriMesh* BooleanOperation::mesh_boolean_union(TriMesh* mesh0, TriMesh* mesh1)
{
CorkTriMesh *in0 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh0);
CorkTriMesh *in1 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh1);
bool isSolid0 = isSolid(*in0);
bool isSolid1 = isSolid(*in1);
//if (!(isSolid0&&isSolid0))return NULL;
CorkTriMesh *m=new CorkTriMesh;
computeUnion(*in0, *in1, m);
TriMesh *result = BooleanOperation::CorkTriMesh_To_TriMesh(m);
return result;
}
TriMesh* BooleanOperation::mesh_boolean_intersection(TriMesh* mesh0, TriMesh* mesh1)
{
CorkTriMesh *in0 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh0);
CorkTriMesh *in1 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh1);
bool isSolid0 = isSolid(*in0);
bool isSolid1 = isSolid(*in1);
//if (!(isSolid0&&isSolid0))return NULL;
CorkTriMesh *m=new CorkTriMesh;
computeIntersection(*in0, *in1, m);
TriMesh *result= BooleanOperation::CorkTriMesh_To_TriMesh(m);
return result;
}
TriMesh* BooleanOperation::mesh_boolean_difference(TriMesh* mesh0, TriMesh* mesh1)
{
CorkTriMesh *in0 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh0);
CorkTriMesh *in1 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh1);
bool isSolid0 = isSolid(*in0);
bool isSolid1 = isSolid(*in1);
//if (!(isSolid0&&isSolid0))return NULL;
CorkTriMesh *m = new CorkTriMesh;
computeDifference(*in0, *in1, m);
TriMesh *result = BooleanOperation::CorkTriMesh_To_TriMesh(m);
return result;
}
TriMesh* BooleanOperation::mesh_boolean_symmetric_difference(TriMesh* mesh0, TriMesh* mesh1)
{
CorkTriMesh *in0 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh0);
CorkTriMesh *in1 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh1);
bool isSolid0 = isSolid(*in0);
bool isSolid1 = isSolid(*in1);
//if (!(isSolid0&&isSolid0))return NULL;
CorkTriMesh *m = new CorkTriMesh;
computeSymmetricDifference(*in0, *in1, m);
TriMesh *result = BooleanOperation::CorkTriMesh_To_TriMesh(m);
return result;
}
TriMesh* BooleanOperation::resolve_Intersections(TriMesh* mesh0, TriMesh* mesh1)
{
CorkTriMesh *in0 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh0);
CorkTriMesh *in1 = BooleanOperation::TriMesh_To_CorkTriMesh(mesh1);
bool isSolid0 = isSolid(*in0);
bool isSolid1 = isSolid(*in1);
//if (!(isSolid0&&isSolid0))return NULL;
CorkTriMesh *m = new CorkTriMesh;
resolveIntersections(*in0, *in1, m);
TriMesh *result = BooleanOperation::CorkTriMesh_To_TriMesh(m);
return result;
}
CorkTriMesh* BooleanOperation::TriMesh_To_CorkTriMesh(TriMesh* mesh)
{
CorkTriMesh *result = new CorkTriMesh;
result->n_vertices = mesh->vertices.size();
result->n_triangles = mesh->faces.size();
result->vertices = new float[result->n_vertices * 3];
result->triangles = new uint[result->n_triangles * 3];
for (int i = 0; i < result->n_triangles; i++)
{
result->triangles[3 * i] = mesh->faces[i][0];
result->triangles[3 * i + 1] = mesh->faces[i][1];
result->triangles[3 * i + 2] = mesh->faces[i][2];
}
for (int i = 0; i < result->n_vertices; i++)
{
result->vertices[3 * i] = mesh->vertices[i][0];
result->vertices[3 * i + 1] = mesh->vertices[i][1];
result->vertices[3 * i + 2] = mesh->vertices[i][2];
}
return result;
}
TriMesh* BooleanOperation::CorkTriMesh_To_TriMesh(CorkTriMesh* in)
{
TriMesh* result = new TriMesh();
result->vertices.resize(in->n_vertices);
result->faces.resize(in->n_triangles);
for (int i = 0; i < in->n_triangles; i++)
{
result->faces[i][0] = in->triangles[3 * i];
result->faces[i][1] = in->triangles[3 * i + 1];
result->faces[i][2] = in->triangles[3 * i + 2];
}
for (int i = 0; i < in->n_vertices; i++)
{
result->vertices[i][0] = in->vertices[3 * i];
result->vertices[i][1] = in->vertices[3 * i + 1];
result->vertices[i][2] = in->vertices[3 * i + 2];
}
freeCorkTriMesh(in);
delete in;
result->need_normals();
return result;
}
void BooleanOperation::OnUnion()
{
// TODO: 在此添加命令处理程序代码
CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CFeatureReuseDoc* pDoc = (CFeatureReuseDoc*)pAppFrame->GetActiveDocument();
TriMesh* in0 = pDoc->meshes[0];
TriMesh *in1 = pDoc->meshes[1];
TriMesh *result = BooleanOperation::mesh_boolean_union(in0, in1);
result->need_Facenormals();
pDoc->meshes.clear();
pDoc->meshes.push_back(result);
}
void BooleanOperation::OnIntersection()
{
// TODO: 在此添加命令处理程序代码
CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CFeatureReuseDoc* pDoc = (CFeatureReuseDoc*)pAppFrame->GetActiveDocument();
TriMesh* in0 = pDoc->meshes[0];
TriMesh *in1 = pDoc->meshes[1];
TriMesh *result = BooleanOperation::mesh_boolean_intersection(in0, in1);
result->need_Facenormals();
pDoc->meshes.clear();
pDoc->meshes.push_back(result);
}
void BooleanOperation::OnDifference()
{
// TODO: 在此添加命令处理程序代码
CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CFeatureReuseDoc* pDoc = (CFeatureReuseDoc*)pAppFrame->GetActiveDocument();
TriMesh* in0 = pDoc->meshes[0];
TriMesh *in1 = pDoc->meshes[1];
TriMesh *result = BooleanOperation::mesh_boolean_difference(in0, in1);
result->need_Facenormals();
pDoc->meshes.clear();
pDoc->meshes.push_back(result);
}
void BooleanOperation::OnSymmetricDifference()
{
// TODO: 在此添加命令处理程序代码
CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CFeatureReuseDoc* pDoc = (CFeatureReuseDoc*)pAppFrame->GetActiveDocument();
TriMesh* in0 = pDoc->meshes[0];
TriMesh *in1 = pDoc->meshes[1];
TriMesh *result = BooleanOperation::mesh_boolean_symmetric_difference(in0, in1);
result->need_Facenormals();
pDoc->meshes.clear();
pDoc->meshes.push_back(result);
}
void BooleanOperation::OnResolveIntersections()
{
// TODO: 在此添加命令处理程序代码
CMainFrame* pAppFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CFeatureReuseDoc* pDoc = (CFeatureReuseDoc*)pAppFrame->GetActiveDocument();
TriMesh* in0 = pDoc->meshes[0];
TriMesh *in1 = pDoc->meshes[1];
TriMesh *result = BooleanOperation::resolve_Intersections(in0, in1);
result->need_Facenormals();
pDoc->meshes.clear();
pDoc->meshes.push_back(result);
}
- 布尔并
- 布尔交
- 布尔差
圆柱减去正方体
正方体减去圆柱