我试图使用C++“剪刀库”(http://www.angusj.com/delphi/clipper.php),但是当我尝试从一个函数从裁剪器库返回其中一个对象时,它似乎变成null或被更改了。
这是我写的函数。唯一相关的行应该是最后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;
}当我调用clipper.execute时,它会在树结构中写入一些轮廓信息。它写正确的信息,我测试过它是正确的。但是,当我返回树时,它似乎没有复制任何东西,由此函数产生的PolyTree是空的。
我确信这个库没有什么问题,我只是在犯一个初学者的c++错误。希望有人知道这可能是什么。
谢谢!
编辑:作为参考,这里有一个多树文档页面(Body.htm)
编辑:我以为裁剪器库不是开源的,但它是开源的。这是代码
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
};发布于 2014-04-03 15:52:23
假设您不想修改(显然设计得很糟糕) Clipper库,您可以像我在评论中建议的那样:
// 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;
}然后,当调用您的函数时:
std::unique_ptr<ClipperLib::PolyTree> tree(yourMeshHandler.trianglesToPolyTreeUnion(/*...*/);
// make use of tree...不过,我还是建议打开一张票(如果有bug跟踪器),或者联系图书馆的作者。
发布于 2014-04-03 15:46:20
在执行任何操作之前,请确保下列程序正确工作:
int main()
{
PolyTree p1;
// fill PolyTree with some values that make sense (please add code to do this)
//...
PolyTree p2 = p1;
PolyTree p3;
p3 = p1;
}这基本上就是我们想要测试的。如果您可以让这段代码正常工作(添加相关的标头和必要的初始化),那么您可以将重点放在函数上。如果上面的代码不起作用,那就是你的答案了。
您需要获得上面的代码来生成正确的副本语义,甚至更重要的是,当main()退出时,在销毁p1、p2和p3时不会发生内存损坏。
因此,您可以修复类来安全地复制,或者忘记它,并与您必须非常小心地在有限的情况下处理的类一起生活(也就是说,您不能像现在这样可靠地返回它的副本)。
发布于 2014-04-03 15:53:05
在冗长的讨论中将所有的答复合并起来记录在案。问题是:
operator=的情况下,调用局部变量的析构函数,清除节点,在函数外部接收的结果为空。PolyTree的代码::Clear()
void PolyTree::Clear()
{
for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
delete AllNodes[i];
AllNodes.resize(0);
Childs.resize(0);
}您可能应该遵循执行模式,并将您的函数定义为:
void MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles,ClipperLib::PolyTree &tree) https://stackoverflow.com/questions/22841696
复制相似问题