请问在返回新网格newmesh时,只有点时可以返回,但组好面之后就出错了是怎么回事?怎么解决?

我用C++对网格mesh进行处理,最后返回newmesh。在newmesh中只有点的时候能返回,但组成面之后return newmesh就出错了,这是为什么?怎么解决?

img

读取文件

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天,您在需要使用的时候【私信】联系我,我会为您补发。