mrkkrj / trianglepp Goto Github PK
View Code? Open in Web Editor NEWC++ wrapper for the original J.P Shevchuk's "Triangle" package
License: Other
C++ wrapper for the original J.P Shevchuk's "Triangle" package
License: Other
When I port this project to a 64-bit platform, I get this problem. The "?" is some number in dex.
Thank you for TrianglePP!
I'm using it in my FE analysis program.
I faced a problem in processing the polygon shape.
If I use min_area = 15000 the TrianglePP goes to infinity work but if I use 30000 or 10000 it works well.
I tried to understand the problem but did not succeed. I only found that "enforcequality()" function gives us that infinity loop.
I guess that "enforcequality" gets not good input data because "while" loop from the original Triangle.c
I've checked this data in the original Triangle it works well.
video:
https://drive.google.com/file/d/15pt8zoaFTUAHmuOHLiZOfiANkiIxnl-G/view?usp=sharing
my test function:
int main()
{
std::vector pslgPoints;
std::vector pslgSegments;
pslgPoints.push_back( Point( 96.38755452, 468.29728961 ));
pslgPoints.push_back( Point( 96.38755452, 1083.30027734 ));
pslgPoints.push_back( Point( 2029.39415452, 1044.64014531 ));
pslgPoints.push_back( Point( 2029.39415452, 820.85321715 ));
pslgPoints.push_back( Point( 2266.38760020, 816.11334821 ));
pslgPoints.push_back( Point( 5096.38755452, 872.71353653 ));
pslgPoints.push_back( Point( 5096.38755422, 257.71036145 ));
pslgPoints.push_back( Point( 1859.23857089, 284.39844942 ));
pslgPoints.push_back( Point( 1021.25668363, 449.67990700 ));
pslgSegments.push_back( Point( 96.38755452, 468.29728961 ));
pslgSegments.push_back( Point( 96.38755452, 1083.30027734 ));
pslgSegments.push_back( Point( 96.38755452, 1083.30027734 ));
pslgSegments.push_back( Point( 2029.39415452, 1044.64014531 ));
pslgSegments.push_back( Point( 2029.39415452, 1044.64014531 ));
pslgSegments.push_back( Point( 2029.39415452, 820.85321715 ));
pslgSegments.push_back( Point( 2029.39415452, 820.85321715 ));
pslgSegments.push_back( Point( 2266.38760020, 816.11334821 ));
pslgSegments.push_back( Point( 2266.38760020, 816.11334821 ));
pslgSegments.push_back( Point( 5096.38755452, 872.71353653 ));
pslgSegments.push_back( Point( 5096.38755452, 872.71353653 ));
pslgSegments.push_back( Point( 5096.38755422, 257.71036145 ));
pslgSegments.push_back( Point( 5096.38755422, 257.71036145 ));
pslgSegments.push_back( Point( 1859.23857089, 284.39844942 ));
pslgSegments.push_back( Point( 1859.23857089, 284.39844942 ));
pslgSegments.push_back( Point( 1021.25668363, 449.67990700 ));
pslgSegments.push_back( Point( 1021.25668363, 449.67990700 ));
pslgSegments.push_back( Point( 96.38755452, 468.29728961 ));
int expected = 0;
bool withQuality = true;
Delaunay trPlsgGenerator(pslgPoints);
trPlsgGenerator.enableMeshIndexGeneration(); // For Iterating using mesh indexes
double min_area = 15000;
trPlsgGenerator.setMinAngle(30.5f);
trPlsgGenerator.setMaxArea(min_area);
bool segmentsOK = trPlsgGenerator.setSegmentConstraint(pslgSegments);
trPlsgGenerator.Triangulate(withQuality);
std::vector< std::vector<double> > mesh_;
std::vector<std::vector<int>> vertices_to_triangles;
// iterate over triangles
std::set<int> vertIds;
Delaunay::Point p0, p1, p2;
int meshIdx0 = -1, meshIdx1 = -1, meshIdx2 = -1;
for (FaceIterator fit = trPlsgGenerator.fbegin(); fit != trPlsgGenerator.fend(); ++fit)
{
fit.Org(p0, meshIdx0); // queries the mesh index!
fit.Dest(p1, meshIdx1);
fit.Apex(p2, meshIdx2);
vertIds.insert(meshIdx0);
vertIds.insert(meshIdx1);
vertIds.insert(meshIdx2);
vertices_to_triangles.push_back({meshIdx0, meshIdx1, meshIdx2});
double x1 = -1;
double y1 = -1;
double x2 = -1;
double y2 = -1;
double x3 = -1;
double y3 = -1;
x1 = p0[0]; y1 = p0[1];
x2 = p1[0]; y2 = p1[1];
x3 = p2[0]; y3 = p2[1];
mesh_.push_back({p0[0], p0[1]});
mesh_.push_back({p1[0], p1[1]});
mesh_.push_back({p2[0], p2[1]});
mesh_.push_back({p0[0], p0[1]});
//std::cout << "[[" << x1 << ", " << y1 << "], " << "[" << x2 << ", " << y2 << "], " << "[" << x3 << ", " << y3 << "]," << "[" << x1 << ", " << y1 << "]],\n";
std::cout << "[" << meshIdx0 << ", " << meshIdx1 << ", " << meshIdx2 << "]\n";
}
return 0;
}
Thanks a lot for wrapping triangle! Made it a lot faster to implement.. But I have to say that using TrianglePP is a bit confusing.
What I want is to simply generate a tessellated mesh from a set of bounding points that will have non-overlapping vertices and indices that map to those vertices.
The solution I came up with is to use a face iterator, and then get points and use an unordered_map of Points with custom hasher to merge overlapping vertices manually. It's reasonably fast, but I have a feeling like there is a better/faster way to do it within this library. For example, I see a checkForDuplicatePoints
but I am not sure how to use it. Reading through the code is unclear.
Here is a solution I am using right now:
class PointHasher
{
public:
using Point = tpp::Delaunay::Point;
size_t operator() (const Point& key) const
{
std::size_t h1 = std::hash<double>{}(key[0]);
std::size_t h2 = std::hash<double>{}(key[1]);
return h1 ^ (h2 << 1);
}
};
class PointKeyeq {
public:
using Point = tpp::Delaunay::Point;
bool operator() (const Point& p0, const Point& p1) const {
return
p0[0] == p1[0] &&
p0[1] == p1[1];
}
};
...
const auto Regenerate = [&]() {
inputPoints.clear();
mesh.indices.clear();
mesh.vertices.clear();
// Make a circle of points
{
const float radX = genParams.radius;
const float radY = genParams.radius;
const float centerX = 0.f;
const float centerY = 0.f;
const int interpolations = genParams.circleSegments;
float step = (2.f * glm::pi<float>()) / interpolations;
for (int i = 0; i < interpolations; i++)
{
float theta = i * step;
auto p = tpp::Delaunay::Point(
centerX + (cos(theta) * radX),
centerY + (sin(theta) * radY)
);
inputPoints.push_back(p);
}
}
tpp::Delaunay gen(inputPoints);
//gen.setMaxArea(0.3f);
gen.setMinAngle(genParams.minAngle);
gen.setMaxArea(genParams.maxArea);
gen.TriangulateConf(true);
using Point = tpp::Delaunay::Point;
const auto ToVert = [](const Point& point) {
Vertex v{ static_cast<float>(point[0]), static_cast<float>(point[1]), 0.f };
v.colr = 0.0f;
v.colg = 0.0f;
v.colb = 0.0f;
return v;
};
// Obtain points and triangles
std::unordered_map<Point, int, PointHasher, PointKeyeq> vertMap; // For merging
vertMap.reserve(1024);
const bool _merge = mergeVertices;
int index = 0;
for (tpp::Delaunay::fIterator it = gen.fbegin(); it != gen.fend(); ++it)
{
Point p0; gen.Org(it, &p0); // These return index of a point in the input list (useless)
Point p1; gen.Dest(it, &p1);
Point p2; gen.Apex(it, &p2);
if (_merge) // with vertex merging
{
const auto AddVert = [&](const tpp::Delaunay::Point& _p)
{
if (vertMap.contains(_p)) // use existing vertex
{
mesh.indices.push_back(vertMap[_p]);
}
else // create a new vertex
{
vertMap[_p] = index;
mesh.indices.push_back(index);
index++;
mesh.vertices.push_back(ToVert(_p));
}
};
AddVert(p0);
AddVert(p1);
AddVert(p2);
}
else // without vertex merging
{
mesh.indices.push_back(index++);
mesh.indices.push_back(index++);
mesh.indices.push_back(index++);
mesh.vertices.push_back(ToVert(p0));
mesh.vertices.push_back(ToVert(p1));
mesh.vertices.push_back(ToVert(p2));
}
}
if (!mesh.IsValid())
{
mesh.Build();
}
else
{
mesh.ReuploadVertices();
mesh.ReuploadIndices();
}
mesh.RecalculateBounds();
};
First of all, thank you so much for the great wrapper!
It works well with QT example and I'm trying to understand your codes with my humble C++ knowledge.
When I looked into the tpp_impl.cpp, the segment part has not been implemented yet, but it's necessary to use holes or constraint outer lines from my understanding.
Can you add this ability?
Thank you in advance! 👍
PS. I'm not familiar with Github yet, so I don't know posting an issue is okay or not. Please let me know if this would be deleted.
I can't seem to get Unreal to accept the library as a Plugin, perhaps I'm making a large oversight but nothing seems to be working. I've successfully before created a plugin from a Dynamic Link Library that had a .Lib and a .DLL file; any chance could you release a version of the library in such a configuration? I tried googling how to do this but couldn't find any tutorial I could understand for an existing library and most examples seem to involve practically rewriting the entire library.
I would appreciate it.
Hi,
Thank you for this implementation.
could you please add support for the D tag?
i.e. remove concavities
I have fixed the issue, will be submitting a pull request soon.
Support for it existed but internally the "c" tag would still be added which caused the concavities to not be removed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.