3

Hello I have a problem with Carve but I am unsure if it is with the implementation or my usage of it.

Here is isolated code which exhibits the issue I have. Essentially I am getting the wrong result, or more specifically I am getting an incorrect vertex in the resultant vertex_storage. This vertex is also included in the face indexes so carve appears to have. I have manually debugged and plotted all the faces so am certain this vertex should not be included.

The vertex included which shouldn't be is highlighted.

enter image description here

The resultant mesh is obviously wrong. Examining it more detail there is one erroneous point included in the vertex_storage which is (150,150,0).

The resultant triangles generated by this include the erroneous vertex o.0

Its a very basic difference operation and I have read that carve has some issues, but I wouldn't have thought it would behave like this with 2 basic meshes (2 cuboids), which make me thinks that it is something I am doing wrong.

Also its frustrating because when debugging (I assume something is seeded/prng) for face 6 (of meshset 0) I get the same vertices, but pretty much always a different ordering.

Here is the source which demonstrates the problem...

#include <carve\mesh.hpp>
#include <carve\csg.hpp>
#include <carve\input.hpp>

#include <Windows.h>

struct MyVector3
{
    MyVector3(float x, float y, float z)
        : x_(x), y_(y), z_(z)
    {
    }

    float x_;
    float y_;
    float z_;
};

struct MyVertex
{
    MyVertex(unsigned int pointIndex)
        : p_(pointIndex)
    {
    }

    unsigned int p_;
    // n_, uv_ etc left out for covienience
};


struct MyTriangle
{
    MyTriangle(unsigned int a, unsigned int b, unsigned int c)
        : a_(a), b_(b), c_(c)
    {
    }

    unsigned int a_;
    unsigned int b_;
    unsigned int c_;
};

struct MyMesh
{
    std::vector<MyVector3> points_;
    std::vector<MyTriangle> triangles_;
    std::vector<MyVertex> vertices_;
};


carve::mesh::MeshSet<3U>* GetCarveMesh(const MyMesh& originalMesh)
{
    carve::input::PolyhedronData data;

    for (unsigned int v = 0; v < originalMesh.vertices_.size(); ++v)
    {
        const MyVector3& point = originalMesh.points_[originalMesh.vertices_[v].p_];
        data.addVertex(carve::geom::VECTOR(point.x_, point.y_, point.z_));
    }

    for (unsigned int t = 0; t < originalMesh.triangles_.size(); t++)
    {
        const MyTriangle& tri = originalMesh.triangles_[t];
        const MyVertex& a = originalMesh.vertices_[tri.a_];
        const MyVertex& b = originalMesh.vertices_[tri.b_];
        const MyVertex& c = originalMesh.vertices_[tri.c_];

        data.addFace(a.p_, b.p_, c.p_);
    }

    return data.createMesh(carve::input::Options());
}

std::list<std::shared_ptr<MyMesh>> GetMyMesh(carve::mesh::MeshSet<3U>* carveMesh)
{
    std::list<std::shared_ptr<MyMesh>> result;

    unsigned int meshStart = 0;
    unsigned int meshEnd = carveMesh->meshes.size();

    for (unsigned int ms = meshStart; ms < meshEnd; ++ms)
    {
        // For each mesh, construct the faces and add the points as we do.
        result.push_back(std::shared_ptr<MyMesh>());

        {
            std::ostringstream oss;
            oss << "mesh " << ms << " has " << carveMesh->meshes[ms]->faces.size() << " faces.\n";

            OutputDebugString(oss.str().c_str());
        }

        unsigned int faceStart = 0;
        unsigned int faceEnd = carveMesh->meshes[ms]->faces.size();

        for (unsigned int f = faceStart; f < faceEnd; ++f)
        {
            //if (f == 10 || f == 11 || f == 6)
            //    continue;

            unsigned int vertexCount = carveMesh->meshes[ms]->faces[f]->n_edges;
            std::vector<MyVector3> points;
            points.reserve(vertexCount);

            std::ostringstream oss;
            oss << " - face " << f << "(" << vertexCount << ") :\n";


            // add each edge in this face... more than 3, then we need to tessellate
            carve::mesh::Edge<3>* currentEdge = carveMesh->meshes[ms]->faces[f]->edge;
            for (unsigned int e = 0; e < vertexCount; ++e)
            {
                MyVector3 point(static_cast<float>(currentEdge->vert->v[0]), static_cast<float>(currentEdge->vert->v[1]), static_cast<float>(currentEdge->vert->v[2]));
                points.push_back(point);

                oss << "[" << e << ":" << point.x_ << ", " << point.y_ << ", " << point.z_ << "]";
                oss << "\n";

                currentEdge = currentEdge->next;
            }

            OutputDebugString(oss.str().c_str());

            //  ... Other operations, tessellation etc

        }
    }
    return result;
}


int main(int argc, char** argv)
{

    // define myMeshA
    MyMesh myMeshA;
    myMeshA.points_.push_back(MyVector3(-150.0f, -150.0f, 0));
    myMeshA.points_.push_back(MyVector3(-150.0f, -150.0f, 2800.0f));
    myMeshA.points_.push_back(MyVector3(150.0f, 150.0f, 0));
    myMeshA.points_.push_back(MyVector3(150.0f, 150.0f, 2800.0f));
    myMeshA.points_.push_back(MyVector3(3430.0f, -150.0f, 0));
    myMeshA.points_.push_back(MyVector3(3430.0f, -150.0f, 2800.0f));
    myMeshA.points_.push_back(MyVector3(3730.0f, 150.0f, 0));
    myMeshA.points_.push_back(MyVector3(3730.0f, 150.0f, 2800.0f));

    myMeshA.vertices_.push_back(MyVertex(0));
    myMeshA.vertices_.push_back(MyVertex(1));
    myMeshA.vertices_.push_back(MyVertex(2));
    myMeshA.vertices_.push_back(MyVertex(3));
    myMeshA.vertices_.push_back(MyVertex(4));
    myMeshA.vertices_.push_back(MyVertex(5));
    myMeshA.vertices_.push_back(MyVertex(6));
    myMeshA.vertices_.push_back(MyVertex(7));

    myMeshA.triangles_.push_back(MyTriangle(0, 1, 3));
    myMeshA.triangles_.push_back(MyTriangle(3, 2, 0));
    myMeshA.triangles_.push_back(MyTriangle(2, 3, 7));
    myMeshA.triangles_.push_back(MyTriangle(7, 6, 2));
    myMeshA.triangles_.push_back(MyTriangle(6, 7, 5));
    myMeshA.triangles_.push_back(MyTriangle(5, 4, 6));
    myMeshA.triangles_.push_back(MyTriangle(4, 5, 1));
    myMeshA.triangles_.push_back(MyTriangle(1, 0, 4));
    myMeshA.triangles_.push_back(MyTriangle(2, 4, 0));
    myMeshA.triangles_.push_back(MyTriangle(4, 2, 6));
    myMeshA.triangles_.push_back(MyTriangle(3, 5, 1));
    myMeshA.triangles_.push_back(MyTriangle(5, 3, 7));

    // define myMeshB
    MyMesh myMeshB;
    myMeshB.points_.push_back(MyVector3(0, 0, 0));
    myMeshB.points_.push_back(MyVector3(0, 0, 2100.0f));
    myMeshB.points_.push_back(MyVector3(0, 300.0f, 0));
    myMeshB.points_.push_back(MyVector3(0, 300.0f, 2100.0f));
    myMeshB.points_.push_back(MyVector3(930.0f, 0, 0));
    myMeshB.points_.push_back(MyVector3(930.0f, 0, 2100.0f));
    myMeshB.points_.push_back(MyVector3(930.0f, 300.0f, 0));
    myMeshB.points_.push_back(MyVector3(930.0f, 300.0f, 2100.0f));

    myMeshB.vertices_.push_back(MyVertex(0));
    myMeshB.vertices_.push_back(MyVertex(1));
    myMeshB.vertices_.push_back(MyVertex(2));
    myMeshB.vertices_.push_back(MyVertex(3));
    myMeshB.vertices_.push_back(MyVertex(4));
    myMeshB.vertices_.push_back(MyVertex(5));
    myMeshB.vertices_.push_back(MyVertex(6));
    myMeshB.vertices_.push_back(MyVertex(7));

    myMeshB.triangles_.push_back(MyTriangle(0, 1, 3));
    myMeshB.triangles_.push_back(MyTriangle(3, 2, 0));
    myMeshB.triangles_.push_back(MyTriangle(2, 3, 7));
    myMeshB.triangles_.push_back(MyTriangle(7, 6, 2));
    myMeshB.triangles_.push_back(MyTriangle(6, 7, 5));
    myMeshB.triangles_.push_back(MyTriangle(5, 4, 6));
    myMeshB.triangles_.push_back(MyTriangle(4, 5, 1));
    myMeshB.triangles_.push_back(MyTriangle(1, 0, 4));
    myMeshB.triangles_.push_back(MyTriangle(2, 4, 0));
    myMeshB.triangles_.push_back(MyTriangle(4, 2, 6));
    myMeshB.triangles_.push_back(MyTriangle(3, 5, 1));
    myMeshB.triangles_.push_back(MyTriangle(5, 3, 7));


    std::unique_ptr<carve::mesh::MeshSet<3U>> meshA(GetCarveMesh(myMeshA));
    std::unique_ptr<carve::mesh::MeshSet<3U>> meshB(GetCarveMesh(myMeshB));

    carve::csg::CSG csg;
    std::unique_ptr<carve::mesh::MeshSet<3U>> carveResult(csg.compute(meshA.get(), meshB.get(), carve::csg::CSG::OP::A_MINUS_B));
    std::list<std::shared_ptr<MyMesh>> result = GetMyMesh(carveResult.get());

    return 0;
}

Associated output

00000020    8.55740356  [12284] mesh 0 has 14 faces.    
00000021    8.55764484  [12284]  - face 0(6) :  
00000022    8.55764484  [12284] [0:-150, -150, 0]   
00000023    8.55764484  [12284] [1:-150, -150, 2800]    
00000024    8.55764484  [12284] [2:150, 150, 2800]  
00000025    8.55764484  [12284] [3:75, 75, 2100]    
00000026    8.55764484  [12284] [4:0, 0, 2100]  
00000027    8.55764484  [12284] [5:0, 0, 1400]  
00000028    8.55826759  [12284]  - face 1(3) :  
00000029    8.55826759  [12284] [0:0, 0, 0] 
00000030    8.55826759  [12284] [1:-150, -150, 0]   
00000031    8.55826759  [12284] [2:0, 0, 1400]  
00000032    8.55878353  [12284]  - face 2(3) :  
00000033    8.55878353  [12284] [0:-150, -150, 2800]    
00000034    8.55878353  [12284] [1:-150, -150, 0]   
00000035    8.55878353  [12284] [2:3430, -150, 0]   
00000036    8.55926609  [12284]  - face 3(3) :  
00000037    8.55926609  [12284] [0:150, 150, 2800]  
00000038    8.55926609  [12284] [1:150, 150, 2100]  
00000039    8.55926609  [12284] [2:75, 75, 2100]    
00000040    8.55982780  [12284]  - face 4(5) :  
00000041    8.55982780  [12284] [0:930, 78.6585, 0] 
00000042    8.55982780  [12284] [1:3430, -150, 0]   
00000043    8.55982780  [12284] [2:-150, -150, 0]   
00000044    8.55982780  [12284] [3:0, 0, 0] 
00000045    8.55982780  [12284] [4:930, 0, 0]   
00000046    8.56040192  [12284]  - face 5(3) :  
00000047    8.56040192  [12284] [0:3430, -150, 0]   
00000048    8.56040192  [12284] [1:3430, -150, 2800]    
00000049    8.56040192  [12284] [2:-150, -150, 2800]    
00000050    8.56112003  [12284]  - face 6(13) : 
00000051    8.56112003  [12284] [0:930, 150, 2100]  
00000052    8.56112003  [12284] [1:465, 150, 2100]  
00000053    8.56112003  [12284] [2:150, 150, 2100]  
00000054    8.56112003  [12284] [3:150, 150, 2800]  
00000055    8.56112003  [12284] [4:3730, 150, 2800] 
00000056    8.56112003  [12284] [5:930, 150, 610.056]   
00000057    8.56112003  [12284] [6:930, 150, 1050]  
00000058    8.56112003  [12284] [7:930, 150, 2100]  
00000059    8.56112003  [12284] [8:930, 150, 1050]  
00000060    8.56112003  [12284] [9:930, 150, 610.056]   
00000061    8.56112003  [12284] [10:150, 150, 0]    
00000062    8.56112003  [12284] [11:150, 150, 2100] 
00000063    8.56112003  [12284] [12:465, 150, 2100] 
00000064    8.56189060  [12284]  - face 7(4) :  
00000065    8.56189060  [12284] [0:930, 150, 0] 
00000066    8.56189060  [12284] [1:3730, 150, 0]    
00000067    8.56189060  [12284] [2:3430, -150, 0]   
00000068    8.56189060  [12284] [3:930, 78.6585, 0] 
00000069    8.56240559  [12284]  - face 8(3) :  
00000070    8.56240559  [12284] [0:3430, -150, 2800]    
00000071    8.56240559  [12284] [1:3430, -150, 0]   
00000072    8.56240559  [12284] [2:3730, 150, 0]    
00000073    8.56300354  [12284]  - face 9(4) :  
00000074    8.56300354  [12284] [0:930, 150, 610.056]   
00000075    8.56300354  [12284] [1:3730, 150, 2800] 
00000076    8.56300354  [12284] [2:3730, 150, 0]    
00000077    8.56300354  [12284] [3:930, 150, 0] 
00000078    8.56469250  [12284]  - face 10(4) : 
00000079    8.56469250  [12284] [0:930, 150, 0] 
00000080    8.56469250  [12284] [1:465, 150, 0] 
00000081    8.56469250  [12284] [2:150, 150, 0] 
00000082    8.56469250  [12284] [3:930, 150, 610.056]   
00000083    8.56473637  [12284]  - face 11(5) : 
00000084    8.56473637  [12284] [0:150, 150, 2100]  
00000085    8.56473637  [12284] [1:150, 150, 0] 
00000086    8.56473637  [12284] [2:0, 0, 0] 
00000087    8.56473637  [12284] [3:0, 0, 1400]  
00000088    8.56473637  [12284] [4:75, 75, 2100]    
00000089    8.56530762  [12284]  - face 12(3) : 
00000090    8.56530762  [12284] [0:3730, 150, 0]    
00000091    8.56530762  [12284] [1:3730, 150, 2800] 
00000092    8.56530762  [12284] [2:3430, -150, 2800]    
00000093    8.56581879  [12284]  - face 13(3) : 
00000094    8.56581879  [12284] [0:75, 75, 2100]    
00000095    8.56581879  [12284] [1:0, 0, 1400]  
00000096    8.56581879  [12284] [2:0, 0, 2100]  
00000097    8.56697178  [12284] mesh 1 has 2 faces. 
00000098    8.56711102  [12284]  - face 0(3) :  
00000099    8.56711102  [12284] [0:150, 150, 2800]  
00000100    8.56711102  [12284] [1:3430, -150, 2800]    
00000101    8.56711102  [12284] [2:-150, -150, 2800]    
00000102    8.56761074  [12284]  - face 1(3) :  
00000103    8.56761074  [12284] [0:3430, -150, 2800]    
00000104    8.56761074  [12284] [1:150, 150, 2800]  
00000105    8.56761074  [12284] [2:3730, 150, 2800]

In the associated output of the face vertices. The veretx (150,150,0) should not be included, but as you can see is included in 3 faces... (faces 6, 10 & 11). This causes the incorrect tessellation.

What is going on here? Is it the way I am using carve, or a problem with carve itself. Any help would be appreciated :)

pingu
  • 8,719
  • 12
  • 50
  • 84
lfgtm
  • 1,037
  • 6
  • 19
  • 1
    I wonder if this question has not received enough attention because no one has been able to figure out what you're asking? I understand that the problem is that an extra vertex ended up in `vertex_storage` (whatever that is), but why should that vertex not be in `vertex_storage`? What are you trying to do? You jumped right into a specific issue without providing the context. Also, is there no way to simplify that example code? It's a lot to look through. I wouldn't be surprised if there was a simple typo hidden in there. – JaMiT Sep 16 '18 at 00:07

0 Answers0