基底的剪切需要将含有高亮的边的点分割成多个点,如果一个点有两个高亮边,那么这个点则需要分裂成两个点,即需要创造一个新点,并将所有的点的信息保存在半边结构中
,我们是以出的半边保存的。
#include<iostream>
#include <OpenMesh\Core\IO\MeshIO.hh>
#include <OpenMesh\Core\Mesh\TriMesh_ArrayKernelT.hh>
#include <OpenMesh\Core\Utils\Property.hh>
struct MyTraits : public OpenMesh::DefaultTraits
{
VertexTraits
{
int some_additional_index;
};
};
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
using namespace std;
int main()
{
MyMesh mesh;
MyMesh mymesh;
OpenMesh::FPropHandleT<bool> fprop_bool;
OpenMesh::EPropHandleT<bool> highlight;
mesh.add_property(fprop_bool, "fprop_bool");
mesh.add_property(highlight, "highlight");
//unsigned int point_size = mesh.n_vertices();
//int num_v = mesh.n_vertices();
//computing the spinning tree;
if (!OpenMesh::IO::read_mesh(mesh, "meshes/cat.off")){
cerr << "can't open the file." << endl;
exit(1);
}
for (MyMesh::EdgeIter e_it = mesh.edges_begin(); e_it != mesh.edges_end(); ++e_it){
mesh.property(highlight, *e_it) = true;
mesh.property(highlight).set_persistent(true);
}
MyMesh::FaceIter f_it = mesh.faces_begin();
vector<MyMesh::FaceHandle> f_vector;
f_vector.push_back(*f_it);
vector<MyMesh::FaceHandle>::iterator f_vector_begin;
int begin = 0;
while (begin != f_vector.size()){
MyMesh::FaceHandle f_handle = f_vector[begin];
for (auto it = mesh.fh_begin(f_handle); it != mesh.fh_end(f_handle); ++it){
MyMesh::HalfedgeHandle halfedge_op_it = mesh.opposite_halfedge_handle(*it);
MyMesh::Halfedge hh = mesh.halfedge(halfedge_op_it);
MyMesh::FaceHandle f_op_it = mesh.face_handle(halfedge_op_it);
if (!mesh.property(fprop_bool, f_op_it)){
mesh.property(fprop_bool, f_op_it) = true;
f_vector.push_back(f_op_it);
mesh.property(highlight, mesh.edge_handle(halfedge_op_it)) = false;
}
}
begin++;
}
//cut unnecessary edges to form homotopy group basis;
bool mark;
while (1){
mark = false;
for (auto v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it){
int number = 0;
for (auto ve_it = mesh.ve_begin(*v_it); ve_it != mesh.ve_end(*v_it); ++ve_it){
if (mesh.property(highlight, *ve_it)){
number++;
}
}
if (number == 1){
mark = true;
for (auto ve_it = mesh.ve_begin(*v_it); ve_it != mesh.ve_end(*v_it); ++ve_it){
mesh.property(highlight, *ve_it) = false;
}
}
}
if (!mark)break;
}
mesh.property(highlight).set_persistent(true);
//Slice-mesh;
OpenMesh::HPropHandleT<MyMesh::VertexHandle> half_vertex;
vector<MyMesh::VertexOHalfedgeIter> voh_vector;
mesh.add_property(half_vertex, "he_vertex");
for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it){
int valence = 0;//highlight edges;
voh_vector.clear();
for (MyMesh::VertexOHalfedgeIter voh_it = mesh.voh_iter(*v_it); voh_it.is_valid(); ++voh_it){
if (mesh.property(highlight, mesh.edge_handle(*voh_it))){
++valence;
voh_vector.push_back(voh_it);
}
}
if (valence == 0){//非高亮边
for (MyMesh::VertexOHalfedgeIter voh_it = mesh.voh_iter(*v_it); voh_it.is_valid(); ++voh_it){
mesh.property(half_vertex, *voh_it) = *v_it;
}
}
if (valence == 2){//高亮边为2的情况,通过顺,逆时针来划分旧的点和新的点的从属范围
MyMesh::VertexHandle vh_new = mesh.new_vertex(mesh.point(*v_it));
int mark = 0;
for (MyMesh::VertexOHalfedgeCCWIter voh_it = mesh.voh_ccwbegin(*v_it); voh_it != mesh.voh_ccwend(*v_it); ++voh_it){
if ((voh_it->operator==(*voh_vector[0])) || (voh_it->operator==(*voh_vector[1]))){
mark++;
}
if (mark == 0 || mark == 2){
mesh.property(half_vertex, *voh_it) = *v_it;
}
else if (mark == 1){
mesh.property(half_vertex, *voh_it) = vh_new;
}
}
}
if (valence == 3){
MyMesh::VertexHandle vh_new1 = mesh.new_vertex(mesh.point(*v_it));
MyMesh::VertexHandle vh_new2 = mesh.new_vertex(mesh.point(*v_it));
MyMesh::VertexHandle vh_new3 = mesh.new_vertex(mesh.point(*v_it));
int mark = 0;
for (MyMesh::VertexOHalfedgeCCWIter voh_it = mesh.voh_ccwbegin(*v_it); voh_it != mesh.voh_ccwend(*v_it); ++voh_it){
if ((*voh_it).operator==(*voh_vector[0]) || (*voh_it).operator==(*voh_vector[1]) || (*voh_it).operator==(*voh_vector[2])){
mark++;
}
if (mark == 0){
mesh.property(half_vertex, *voh_it) = *v_it;
}
else if (mark == 1){
mesh.property(half_vertex, *voh_it) = vh_new2;
}
else if (mark == 2){
mesh.property(half_vertex, *voh_it) = vh_new3;
}
else if (mark == 3){
mesh.property(half_vertex, *voh_it) = *v_it;
}
}
}
}
cout << "what is it?" << endl;
//MyMesh mymesh;
vector<MyMesh::VertexHandle> v_handles;
vector<MyMesh::VertexHandle> vhnew;
map<MyMesh::VertexHandle,int>v_handle_map;
vector<OpenMesh::VertexHandle> fv_handles;
vector<OpenMesh::FaceHandle> f_handles;
for (MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it){
f_handles.push_back(*f_it);
}
/*
for (int i = 0; i < f_handles.size(); i++){
MyMesh::FaceHandle f = f_handles[i];
fv_handles.clear();
for (MyMesh::FaceHalfedgeIter fh_it = mesh.fh_iter(f); fh_it.is_valid(); ++fh_it){
int count = 0;
for (int i = 0; i < v_handles.size(); i++){
if (mesh.property(half_vertex, *fh_it) != v_handles[i]){
count++; continue;
}
if (mesh.property(half_vertex, *fh_it) == v_handles[i]){
fv_handles.push_back(vhnew[i]);
break;
}
}
if (count == v_handles.size()){
MyMesh::VertexHandle vh = mymesh.add_vertex(mesh.point(mesh.property(half_vertex, *fh_it)));
fv_handles.push_back(vh);
vhnew.push_back(vh);
v_handles.push_back(mesh.property(half_vertex, *fh_it));
}
}
mymesh.add_face(fv_handles);
}
*/ //上面的代码由于太耗费时间,所以用map来缩小时间复杂度,通过一个map来记录新建的点的idx,从而直接索引得到所对应的vertexhandle
for (int i = 0; i < f_handles.size(); i++){
MyMesh::FaceHandle f = f_handles[i];
fv_handles.clear();
for (MyMesh::FaceHalfedgeIter fh_it = mesh.fh_iter(f); fh_it.is_valid(); ++fh_it){
MyMesh::VertexHandle v_handles_temp = mesh.property(half_vertex, *fh_it);
int int_temp = v_handles_temp.idx();
if (v_handle_map[v_handles_temp] > 0){
fv_handles.push_back(mesh.vertex_handle(v_handle_map[v_handles_temp]-1));
}
else{
MyMesh::VertexHandle vh = mymesh.add_vertex(mesh.point(mesh.property(half_vertex, *fh_it)));
v_handle_map[v_handles_temp] = vh.idx()+1;
fv_handles.push_back(vh);
}
}
mymesh.add_face(fv_handles);
}
//这个代码的难点在于需要重新生成新点,然后在新点的基础上重建mesh,在这里浪费时间较多。
//for (int i = 0; i < v_handles.size(); i++){ cout << v_handles[i] << endl; }
//for (int i = 0; i < vhnew.size(); i++){ cout << vhnew[i] << endl; }
// write mesh to output.obj
try
{
if (!OpenMesh::IO::write_mesh(mymesh, "cat1.om"))
{
std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;
return 1;
}
}
catch (std::exception& x)
{
std::cerr << x.what() << std::endl;
return 1;
}
cin.get();
return 0;
}