三维CAD建模 基于Brep的扫成与欧拉操作
基于B-rep的建模操作及其算法
上了高老师的cad课,高老师的课十几年来不变的大作业就是基于半边结构的5个欧拉操作和sweep扫成cad模型的实现,以下是高老师上课时讲的一些干货,brep的基础知识请自行百度。
欧拉操作
- 欧拉公式
欧拉公式是基于初中的欧拉公式v-e+f=2的拓展,在有内环(洞)的时候也能成立,欧拉操作就是基于欧拉公式的操作
v(
vertice
)-e(edge
)+f(front
)=2(s(solid
)-h(handle
穿透))+r(内环
) 整体构造成5维超平面
-
欧拉操作的基本思想
- 提供一组拓扑结构生成操作
- 基于欧拉公式使其具有一定的
-
欧拉操作的选取
v e f h r s meaning 1 1 0 0 0 0 mev 0 1 1 0 0 0 mef 1 0 1 0 0 1 mvfs 0 -1 0 0 1 0 kemr 0 0 -1 1 1 0 kfmre - 其中k=kill m=make vfs如上
- 有时s=split
- 增加一个操作semv
- 每个操作都有一个逆操作 用k替换m用m替换k 总计12个操作
-
欧拉操作的功能与实现
以简单的两个操作为例:- mvfs
- 构造一个体,外面和边,这里编程时注意,在构造一个无依赖边的点的时候也构造了一个空面和一个空体
- lp->ledge=NULL
- mev
- 构造一个新点,和一个接新点和给定点的边
- HalfEdge * mev(v1,lp) lp=loop
有效性原则,使得新定义的半边与其所属环中的其他半边形成一个有向封闭的环。
- mvfs
数据结构
本项目主要基于qt5开发
#ifndef DS_H
#define DS_H
#include <QWidget>
#include <stdlib.h>
#include <QVector3D>
#include <vector>
#include <iostream>
#include <QDebug>
using namespace std;
class Solid;
class Face;
class Loop;
class HalfEdge;
class Vertex;
class Edge;
class Solid
{
public:
Face *faces; // list of all faces to construct this solid
Edge *edges; // list of all edges to construct this solid
void printEdge();
Solid() : faces(nullptr), edges(nullptr){}
};
class Face
{
public:
int id;
Solid *solid; // the solid which the face belong to
Loop *outLp; // out loop of the face--construct the face
Loop *innerLp;//inner_lp of the face--inner loop
Face *next;//for face list in solid
Face *pre;
static int numFace;
void addInerLoop(Loop *&l);
Face() : id(0), solid(nullptr), outLp(nullptr), innerLp(nullptr),next(nullptr),pre(nullptr){
id=numFace++;
}
~Face();
};
class Loop
{
public :
int id;
static vector<Loop*> loopArray;//an Automatic maintenance pointer array
static int numLoop;
HalfEdge *halfedges; // list of all halfeges to construct this loop
Face *face; // the face that constructed by this loop
Loop *next;
Loop *pre;
QVector3D normal;
void printLoop();//print Loop halfedge info for Debug
QVector3D getOritation();//get normal 3Dvector
Loop() : id(0), halfedges(nullptr), face(nullptr), next(nullptr), pre(nullptr){loopArray.push_back(this);id=numLoop++;
}//for sake of plot loop
};
class Edge
{
public:
HalfEdge *half_l; //the edge's left halfedge
HalfEdge *half_r; //the edge's right halfedge
Edge *next;
Edge *pre;
int id;
static int numEdge;
Edge() : half_l(nullptr), half_r(nullptr), next(nullptr), pre(nullptr){id=numEdge++;}
};
class HalfEdge
{
public:
Edge *edge; //this halfedge belong to which edge
Vertex *sv; //the start vertex of this halfedge
Vertex *ev; //the end vertex of this halfedge
Loop *lp; //pointer to the loop that this halfedge belong to
HalfEdge *next;
HalfEdge *pre;
HalfEdge *brother;//useless
void printHfEdge();
HalfEdge() : edge(nullptr), sv(nullptr), lp(nullptr), next(nullptr), pre(nullptr), brother(nullptr){}
};
class Vertex
{
public:
int id;
static vector<Vertex*> vertexArray;//an Automatic maintenance pointer array
QVector3D coordinate;//coordinate of the vertex (x, y, z)
Vertex *next;
Vertex *pre;
static int numVertex;
Vertex(QVector3D q) : next(nullptr), pre(nullptr)
{
coordinate=q;
id=numVertex++;
vertexArray.push_back(this);
}
};
#endif
图形交互界面