CGAL / cgal

The public CGAL repository, see the README below
https://github.com/CGAL/cgal#readme
Other
4.98k stars 1.39k forks source link

Transform Polyhedron to Nef_polyhedron occur error #4313

Closed Haoqiantao closed 5 years ago

Haoqiantao commented 5 years ago

Issue Details

When i want to Transform a Polyhedron to Nef_polyhedron, it occur an error that is " expr = 0x0137b780 "pe_prev->is_border() || internal::Plane_constructor::get_plane(pe_prev->facet(), pe_prev->facet()->plane()). has_on(pe_prev->opposite()->vertex()->point())"" I have already construct the Polyhedron, but it can not transform to Nef_polyhedron through the method Nef(polyhedron), i am not sure the error is beacuse of the polyhedron that i construct can not transform to a Nef_polyhedron, please see my code under.

Source Code

        VFMesh meshC;
        Polyhedron  polyhedronC;
        meshC.pointlist.push_back(CGALPoint(0, 0, 0));
    meshC.pointlist.push_back(CGALPoint(0, 10, 0));
    meshC.pointlist.push_back(CGALPoint(10, 10, 0));
    meshC.pointlist.push_back(CGALPoint(10, 0, 0));
    meshC.pointlist.push_back(CGALPoint(0, 0, 10));
    meshC.pointlist.push_back(CGALPoint(0, 10, 10));
    meshC.pointlist.push_back(CGALPoint(10, 10, 10));
    meshC.pointlist.push_back(CGALPoint(10, 0, 10));
    meshC.pointlist.push_back(CGALPoint(20, 10, 0));
    meshC.pointlist.push_back(CGALPoint(20, 0, 0));
    meshC.pointlist.push_back(CGALPoint(20, 10, -10));
    meshC.pointlist.push_back(CGALPoint(20, 0, -10));

    std::vector<int> faceA{ 0, 3, 2, 1 };
    std::vector<int> faceB{ 4, 5, 6, 7 };
    std::vector<int> faceC{ 4, 0, 1, 5 };
    std::vector<int> faceD{ 6, 5, 1, 2 };
    std::vector<int> faceE{ 4, 7, 3, 0 };
    std::vector<int> faceF{ 7, 6, 9, 8 };
    std::vector<int> faceG{ 3, 11, 10, 2 };
    std::vector<int> faceH{ 9, 6, 2, 10 };
    std::vector<int> faceI{ 7, 8, 11, 3 };
    std::vector<int> faceJ{ 8, 9, 10, 11 };
        mesh2polyhedron(meshC, polyhedronC);
        Nef_polyhedron nefC(polyhedronC);`

I construct a Polyhedron by these points and faces, the Polyhedron is just like the picture show image

Environment

sloriot commented 5 years ago

You input is not a valid polyhedral surface, it has self-intersections. According to your picture and mine: mine I guess you simply mix up some indices in a face + the orientation of all faces is wrong.

Using the following indices should fixes the issue:

1 2 3 0
7 6 5 4
5 1 0 4
2 1 5 6
0 3 7 4
2 10 11 3
0 2 6 8
3 11 9 7
11 10 8 9
9 8 6 7

It is possible to load random faces in Nef by using CGAL::OFF_to_nef_3().

Haoqiantao commented 5 years ago

I am sorry to ask for advice Again, I know that i make a mistake of using the index of the points , and i have another Polyhedron that i am sure it is in the correct index, but it can not construct the Nef_polyhedron. I do not know if it is because of the precision that i do not meet or not. please help me to check it. The date are shown under. meshA.pointlist.push_back(CGALPoint(-12007, -6605, 16969)); meshA.pointlist.push_back(CGALPoint(-12207, -6605, 16969)); meshA.pointlist.push_back(CGALPoint(-12207, -6605, 16386)); meshA.pointlist.push_back(CGALPoint(-12007, -6605, 16386)); meshA.pointlist.push_back(CGALPoint(-12007, -5520, 17619)); meshA.pointlist.push_back(CGALPoint(-12207, -5720, 17499)); meshA.pointlist.push_back(CGALPoint(-12207, -5581, 16999)); meshA.pointlist.push_back(CGALPoint(-12007, -5581, 16999));

meshA.pointlist.push_back(CGALPoint(-12007, -2020, 17619));
meshA.pointlist.push_back(CGALPoint(-12207, -2020, 17499));
meshA.pointlist.push_back(CGALPoint(-12207, -2020, 16999));
meshA.pointlist.push_back(CGALPoint(-12007, -2020, 16999));

    std::vector<int> face1{ 0, 1, 2, 3 };
std::vector<int> face2{ 0, 4, 5, 1 };
std::vector<int> face3{ 2, 6, 7, 3 };
std::vector<int> face4{ 0, 3, 7, 4 };
std::vector<int> face5{ 5, 6, 2, 1 };
std::vector<int> face6{ 4, 8, 9, 5 };
std::vector<int> face7{ 7, 11, 8, 4 };
std::vector<int> face8{ 7, 6, 10, 11 };
std::vector<int> face9{ 6, 5, 9, 10 };
std::vector<int> face10{ 9, 8, 11, 10 };

it is shown just like this. Thank you.

sloriot commented 5 years ago

This one is fine for me and I could convert it to nef. Without seeing your program I can't tell what's wrong.

Haoqiantao commented 5 years ago

I make an Console Project just to transform the polyhedron to Nef_polyhedron, this cpp shows my code. it shows an error that is expr = 0x00d2b3d0 "pe_prev->is_border() || internal::Plane_constructor::get_plane(pe_prev->facet(), pe_prev->facet()->plane()). has_on(pe_prev->opposite()->vertex()->point())"

Haoqiantao commented 5 years ago
#include` "stdafx.h"
#include "fstream"
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
//#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>

//#include <CGAL/Cartesian.h>
//typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Cartesian<CGAL::Gmpq> Kernel;

typedef CGAL::Polyhedron_3<Kernel>  Polyhedron;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
typedef Polyhedron::HalfedgeDS HalfedgeDS;
typedef HalfedgeDS::Vertex   CGALVertex;
typedef CGALVertex::Point CGALPoint;
typedef Polyhedron::Point_iterator Point_iterator;
typedef Polyhedron::Facet_iterator Facet_iterator;
typedef Polyhedron::Halfedge_around_facet_circulator Halfedge_facet_circulator;

struct POLYHEDRON
{
    double * Points;
    int PointCount;
    int ** Polys;
    int PolyCount;
};

struct VFMesh
{
    std::vector<CGALPoint> pointlist;//点;
    std::vector<std::vector<int>> facelist;//面,保存面的点的索引;
};

class CgalPolyhedron : public CGAL::Modifier_base<HalfedgeDS>
{
public:
public:
    CgalPolyhedron(VFMesh &mesh) : m_mesh(mesh) {}
    void operator()(HalfedgeDS& hds)
    {
        CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B(hds, true);
        int pointsize = m_mesh.pointlist.size();
        int facessize = m_mesh.facelist.size();
        B.begin_surface(pointsize, facessize, 0);
        for (int i = 0; i < pointsize; i++)
        {
            B.add_vertex(CGALPoint(m_mesh.pointlist[i].x(), m_mesh.pointlist[i].y(), m_mesh.pointlist[i].z()));
        }
        for (int i = 0; i < facessize; i++)
        {
            B.begin_facet();
            for (int j = 0; j < m_mesh.facelist[i].size(); j++)
            {
                B.add_vertex_to_facet(m_mesh.facelist[i][j]);
            }
            B.end_facet();
        }
        B.end_surface();
    }
private:
    VFMesh m_mesh;
};

void mesh2polyhedron(VFMesh &mesh, Polyhedron &P)
{
    CgalPolyhedron builder(mesh);
    P.delegate(builder);
}

int _tmain(int argc, _TCHAR* argv[])
{
    VFMesh meshA, meshB, resultmesh, meshC;
    Polyhedron polyhedronA, polyhedronB, result, polyhedronC;

    meshA.pointlist.push_back(CGALPoint(-12007, -6605, 16969));
    meshA.pointlist.push_back(CGALPoint(-12207, -6605, 16969));
    meshA.pointlist.push_back(CGALPoint(-12207, -6605, 16386));
    meshA.pointlist.push_back(CGALPoint(-12007, -6605, 16386));
    meshA.pointlist.push_back(CGALPoint(-12007, -5520, 17619));
    meshA.pointlist.push_back(CGALPoint(-12207, -5720, 17499));
    meshA.pointlist.push_back(CGALPoint(-12207, -5581, 16999));
    meshA.pointlist.push_back(CGALPoint(-12007, -5581, 16999));

    meshA.pointlist.push_back(CGALPoint(-12007, -2020, 17619));
    meshA.pointlist.push_back(CGALPoint(-12207, -2020, 17499));
    meshA.pointlist.push_back(CGALPoint(-12207, -2020, 16999));
    meshA.pointlist.push_back(CGALPoint(-12007, -2020, 16999));

    std::vector<int> face7{ 0, 1, 2, 3 };
    std::vector<int> face8{ 0, 4, 5, 1 };
    std::vector<int> face9{ 2, 6, 7, 3 };
    std::vector<int> face10{ 0, 3, 7, 4 };

    std::vector<int> face11{ 5, 6, 2, 1 };
    std::vector<int> face12{ 4, 8, 9, 5 };
    std::vector<int> face13{ 7, 11, 8, 4 };
    std::vector<int> face14{ 7, 6, 10, 11 };
    std::vector<int> face15{ 6, 5, 9, 10 };
    std::vector<int> face16{ 9, 8, 11, 10 };

    meshA.facelist.push_back(face7);
    meshA.facelist.push_back(face8);
    meshA.facelist.push_back(face9);
    meshA.facelist.push_back(face10);
    meshA.facelist.push_back(face11);
    meshA.facelist.push_back(face12);
    meshA.facelist.push_back(face13);
    meshA.facelist.push_back(face14);
    meshA.facelist.push_back(face15);
    meshA.facelist.push_back(face16);

    mesh2polyhedron(meshA, polyhedronA);    
    Nef_polyhedron nefA(polyhedronA);

    return 0;
}

I do not konw how to send the cpp, so I show you my code

Haoqiantao commented 5 years ago

Hello, is there any question in my code?

sloriot commented 5 years ago

One of your faces is composed of 4 points that are not coplanar. You have to use the function CGAL::OFF_to_nef_3() or triangulate your input polyhedron using CGAL::Polygon_mesh_processing::triangulate_faces().

Haoqiantao commented 5 years ago

OK, I will try. It has been a problem to me for a long time. Thank you for your help.