我用C++对网格mesh进行处理,最后返回newmesh。在newmesh中只有点的时候能返回,但组成面之后return newmesh就出错了,这是为什么?怎么解决?
读取文件
void readfile(string file) {
// 请求顶点法线 vertex normals
mesh.request_vertex_normals();
//如果不存在顶点法线,则报错
if (!mesh.has_vertex_normals())
{
cout << "错误:标准定点属性 “法线”不存在" << endl;
return;
}
// 如果有顶点发现则读取文件
OpenMesh::IO::Options opt;
if (!OpenMesh::IO::read_mesh(mesh, file, opt))
{
cout << "无法读取文件:" << file << endl;
return;
}
else cout << "成功读取文件:" << file << endl;
cout << endl; // 为了ui显示好看一些
//如果不存在顶点法线,则计算出
if (!opt.check(OpenMesh::IO::Options::VertexNormal))
{
// 通过面法线计算顶点法线
mesh.request_face_normals();
// mesh计算出顶点法线
mesh.update_normals();
// 释放面法线
mesh.release_face_normals();
}
for (MyMesh::VertexIter v_it=mesh.vertices_begin();v_it!=mesh.vertices_end();++v_it){
MyMesh::Point pt=mesh.point(v_it.handle());
center[0]+=pt.data()[0];
center[1]+=pt.data()[1];
center[2]+=pt.data()[2];
vertex_num++;
}
center[0]=center[0]/vertex_num;
center[1]=center[1]/vertex_num;
center[2]=center[2]/vertex_num;
std::cout<<"center X:"<<center[0]<<" center Y:"<<center[1]<<" center Z:"<<center[2]<<std::endl;
std::cout<<"vertex_num:"<<vertex_num<<std::endl;
mesh.request_face_status();
mesh.request_vertex_status();
mesh.request_halfedge_status();
for (auto v_itr=mesh.vertices_begin();v_itr!=mesh.vertices_end();++v_itr)
{
mesh.status(*v_itr).set_tagged(false);
}
for (auto h_itr=mesh.halfedges_begin();h_itr!=mesh.halfedges_end();++h_itr)
{
mesh.status(*h_itr).set_tagged(false);
}
mesh=LoopSubdivision(); //对mesh进行处理
}
Loopsudivision中调用的函数,用于更新旧顶点与插入新顶点
MyMesh::Point Update(OpenMesh::VertexHandle v)
{
MyMesh::Point pa=mesh.point(v);
MyMesh::Point a;
a.data()[0]=0;
a.data()[1]=0;
a.data()[2]=0;
if (mesh.is_boundary(v))
{
for (auto it=mesh.vih_begin(v);it!=mesh.vih_end(v);++it)
{
auto he=it.handle();
if (mesh.is_boundary(he))
{
auto v1=mesh.from_vertex_handle(he);
auto v2=mesh.to_vertex_handle(he);
if (v!=v1)
{
MyMesh::Point b=mesh.point(v1);
a.data()[0]=a.data()[0]+b.data()[0];
a.data()[1]=a.data()[1]+b.data()[1];
a.data()[2]=a.data()[2]+b.data()[2];
}
if (v!=v2)
{
MyMesh::Point b=mesh.point(v1);
a.data()[0]=a.data()[0]+b.data()[0];
a.data()[1]=a.data()[1]+b.data()[1];
a.data()[2]=a.data()[2]+b.data()[2];
}
}
}
a.data()[0]=0.75*pa.data()[0]+0.125*a.data()[0];
a.data()[1]=0.75*pa.data()[1]+0.125*a.data()[1];
a.data()[2]=0.75*pa.data()[2]+0.125*a.data()[2];
}
else
{
int n=0;
for (MyMesh::VertexVertexIter itt=mesh.vv_iter(v);itt.is_valid();++itt)
{
auto v0=itt.handle();
MyMesh::Point b=mesh.point(v0);
a.data()[0]=a.data()[0]+b.data()[0];
a.data()[1]=a.data()[1]+b.data()[1];
a.data()[2]=a.data()[2]+b.data()[2];
n++;
}
double w=0.375+0.25*cos(2*3.1415926/n);
w=w*w;
w=0.625-w;
w=w/n;
a.data()[0]=(1-n*w)*pa.data()[0]+w*a.data()[0];
a.data()[1]=(1-n*w)*pa.data()[1]+w*a.data()[1];
a.data()[2]=(1-n*w)*pa.data()[2]+w*a.data()[2];
}
return a;
}
MyMesh::Point Insert(OpenMesh::HalfedgeHandle he1)
{
auto he2=mesh.opposite_halfedge_handle(he1);
auto he3=mesh.next_halfedge_handle(he1);
auto he4=mesh.next_halfedge_handle(he2);
auto v1=mesh.to_vertex_handle(he1);
auto v2=mesh.to_vertex_handle(he2);
auto v3=mesh.to_vertex_handle(he3);
auto v4=mesh.to_vertex_handle(he4);
MyMesh::Point pa=mesh.point(v1),pb=mesh.point(v2),pc=mesh.point(v3),pd=mesh.point(v4);
MyMesh::Point a;
if (mesh.is_boundary(he1))
{
a.data()[0]=(pa.data()[0]+pb.data()[0])/2;
a.data()[1]=(pa.data()[1]+pb.data()[1])/2;
a.data()[2]=(pa.data()[2]+pb.data()[2])/2;
}
else
{
a.data()[0]=0.375*(pa.data()[0]+pb.data()[0])+0.125*(pc.data()[0]+pd.data()[0]);
a.data()[1]=0.375*(pa.data()[1]+pb.data()[1])+0.125*(pc.data()[1]+pd.data()[1]);
a.data()[2]=0.375*(pa.data()[2]+pb.data()[2])+0.125*(pc.data()[2]+pd.data()[2]);
}
mesh.status(he1).set_tagged(true);
mesh.status(he2).set_tagged(true);
return a;
}
将更新后的顶点和插入的顶点放入newmesh中之后组成面返回newmesh
MyMesh LoopSubdivision()
{
MyMesh newmesh;
map<OpenMesh::HalfedgeHandle,OpenMesh::VertexHandle>mapv1;
map<OpenMesh::VertexHandle,OpenMesh::VertexHandle>mapv2;
for (auto it=mesh.vertices_begin();it!=mesh.vertices_end();++it)
{
auto v0=it.handle();
OpenMesh::VertexHandle v;
MyMesh::Point a=Update(v0);
v=newmesh.add_vertex(a);
mapv2.insert(pair<OpenMesh::VertexHandle,OpenMesh::VertexHandle>(v0,v));
}
for (auto it=mesh.halfedges_begin();it!=mesh.halfedges_end();++it)
{
auto he1=it.handle();
auto he2=mesh.opposite_halfedge_handle(he1);
if (mesh.status(he1).tagged()==false)
{
OpenMesh::VertexHandle v;
MyMesh::Point a=Insert(he1);
v=newmesh.add_vertex(a);
mapv1.insert(pair<OpenMesh::HalfedgeHandle,OpenMesh::VertexHandle>(he1,v));
mapv1.insert(pair<OpenMesh::HalfedgeHandle,OpenMesh::VertexHandle>(he2,v));
}
}
for (auto it=mesh.faces_begin();it!=mesh.faces_end();++it)
{
vector<OpenMesh::VertexHandle> vh2;
auto he1=mesh.fh_begin(it.handle());
auto he2=mesh.next_halfedge_handle(he1);
auto he3=mesh.next_halfedge_handle(he2);
auto v1=mesh.from_vertex_handle(he1);
auto v2=mesh.from_vertex_handle(he2);
auto v3=mesh.from_vertex_handle(he3);
OpenMesh::VertexHandle v4,v5,v6,v11,v22,v33;
map<OpenMesh::HalfedgeHandle,OpenMesh::VertexHandle>::iterator iter1;
iter1=mapv1.find(he1);
v4=iter1->second;
vh2.push_back(v4);
iter1=mapv1.find(he2);
v5=iter1->second;
vh2.push_back(v5);
iter1=mapv1.find(he3);
v6=iter1->second;
vh2.push_back(v6);
map<OpenMesh::VertexHandle,OpenMesh::VertexHandle>::iterator iter2;
iter2=mapv2.find(v1);
v11=iter2->second;
vh2.push_back(v11);
iter2=mapv2.find(v2);
v22=iter2->second;
vh2.push_back(v22);
iter2=mapv2.find(v3);
v33=iter2->second;
vh2.push_back(v33);
std::vector<MyMesh::VertexHandle>face_vhandles;
face_vhandles.clear();
face_vhandles.push_back(vh2[0]);
face_vhandles.push_back(vh2[1]);
face_vhandles.push_back(vh2[2]);
newmesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vh2[0]);
face_vhandles.push_back(vh2[4]);
face_vhandles.push_back(vh2[1]);
newmesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vh2[1]);
face_vhandles.push_back(vh2[5]);
face_vhandles.push_back(vh2[2]);
newmesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vh2[2]);
face_vhandles.push_back(vh2[3]);
face_vhandles.push_back(vh2[0]);
newmesh.add_face(face_vhandles);
}
cout<<"---------------"<<endl;
return newmesh;
}
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。