Search code examples
c++clipperlib

C++ Cannot Return Object From Function


I am trying to use the C++ "Clipper Library" (http://www.angusj.com/delphi/clipper.php), but when I try to return one of the objects from the clipper library from a function, it seems to become null or is altered somehow

Here is the function I wrote. The only relevant lines should be the last 3.

ClipperLib::PolyTree MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
{
    // Make all of the triangles CW
    for (auto& triangle : triangles)
    {
        triangle.makeClockwise();
    }
    // Set up the Clipper
    ClipperLib::Clipper clipper;
    // To take a union, add all the paths as "subject" paths
    for (auto& triangle : triangles)
    {
        ClipperLib::Path triContour(3);
        triContour[0] = convertGLMToClipperPoint(triangle.getVertex(0));
        triContour[1] = convertGLMToClipperPoint(triangle.getVertex(1));
        triContour[2] = convertGLMToClipperPoint(triangle.getVertex(2));
        clipper.AddPath(triContour, ClipperLib::PolyType::ptSubject, true);
    }
    // Now get the PolyTree representing the contours
    ClipperLib::PolyTree tree;
    clipper.Execute(ClipperLib::ClipType::ctUnion, tree);
    return tree;
}

When I call clipper.execute, it writes into the tree structure some contour information. It writes the correct information, and I've tested that it's correct. However, when I return the tree, it doesn't seem to copy anything, and the PolyTree that results from this function is empty.

I'm sure that there's nothing wrong with the library and that I'm just making a beginner c++ mistake here. Hopefully someone has an idea of what it might be.

Thanks!

edit: For reference, here is a documentation page for the polytree (http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm)

edit: I thought the clipper library wasn't open source, but it is. Here is the code

typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;

class PolyNode 
{ 
public:
    PolyNode();
    Path Contour;
    PolyNodes Childs;
    PolyNode* Parent;
    PolyNode* GetNext() const;
    bool IsHole() const;
    bool IsOpen() const;
    int ChildCount() const;
private:
    unsigned Index; //node index in Parent.Childs
    bool m_IsOpen;
    JoinType m_jointype;
    EndType m_endtype;
    PolyNode* GetNextSiblingUp() const;
    void AddChild(PolyNode& child);
    friend class Clipper; //to access Index
    friend class ClipperOffset; 
};

class PolyTree: public PolyNode
{ 
public:
    ~PolyTree(){Clear();};
    PolyNode* GetFirst() const;
    void Clear();
    int Total() const;
private:
    PolyNodes AllNodes;
    friend class Clipper; //to access AllNodes
};

Solution

  • Assuming you don't want to modify the (obviously badly designed) Clipper library, you can do it like I suggested in my comment:

    // Make sure to have this at the top of your header file:
    #include <memory>
    
    std::unique_ptr<ClipperLib::PolyTree> MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
    {
        // Rest of your code...
    
        std::unique_ptr<ClipperLib::PolyTree> tree(new ClipperLib::PolyTree);
        clipper.Execute(ClipperLib::ClipType::ctUnion, *tree);
        return tree;
    }
    

    Then, when calling your function:

    std::unique_ptr<ClipperLib::PolyTree> tree(yourMeshHandler.trianglesToPolyTreeUnion(/*...*/);
    
    // make use of tree...
    

    Still, I would suggest opening a ticket (if there's a bug tracker) or contacting the library's author about this issue.