After i try to update my project by move from CSG to CSG2.
I found some problem with CSG2.
I make example here.
CSG and CSG2 has different result, and CSG got better result.
If i did something wrong or there is workaround, any suggestion is welcome.
HiGreg
December 12, 2024, 11:57am
3
Still waiting for expert reply, but I could guess the sliver not removed might be undefined. If you need it fixed right now, you can very slightly enlarge the cutout shape:
I look at mainfold library already.
This library compare floating point without regard to their precision.
* @param radiusLow Radius of bottom circle. Must be positive.
* @param radiusHigh Radius of top circle. Can equal zero. Default is equal to
* radiusLow.
* @param circularSegments How many line segments to use around the circle.
* Default is calculated by the static Defaults.
* @param center Set to true to shift the center to the origin. Default is
* origin at the bottom.
*/
Manifold Manifold::Cylinder(double height, double radiusLow, double radiusHigh,
int circularSegments, bool center) {
if (height <= 0.0 || radiusLow <= 0.0) {
return Invalid();
}
const double scale = radiusHigh >= 0.0 ? radiusHigh / radiusLow : 1.0;
const double radius = fmax(radiusLow, radiusHigh);
const int n = circularSegments > 2 ? circularSegments
: Quality::GetCircularSegments(radius);
SimplePolygon circle(n);
const double dPhi = 360.0 / n;
for (int i = 0; i < n; ++i) {
In programming sometime, we need to trade performance with correctness.
and some reference for who don’t understand what’s i talk about. here
[edit]
They did some but it seem not enough.
const vec3 origin = vertPos[halfedge[3 * referenceTri].startVert];
const vec3 normal = la::normalize(
la::cross(vertPos[halfedge[3 * referenceTri + 1].startVert] - origin,
vertPos[halfedge[3 * referenceTri + 2].startVert] - origin));
for (const int i : {0, 1, 2}) {
const vec3 vert = vertPos[halfedge[3 * tri + i].startVert];
// If any component vertex is not coplanar with the component's reference
// triangle, unmark the entire component so that none of its triangles are
// marked coplanar.
if (std::abs(la::dot(normal, vert - origin)) > tolerance) {
reinterpret_cast<std::atomic<int>*>(&comp2tri[component])
->store(-1, std::memory_order_relaxed);
break;
}
}
}
};
int GetLabels(std::vector<int>& components,
const Vec<std::pair<int, int>>& edges, int numNodes) {
this is why we are actually keeping both CSG and CSG2. they are both useful depending on the cases. Like @HiGreg mentioned you have an option to still use CSG2 (by far faster)
If you look at Manifold Library · elalish/manifold Wiki · GitHub , it tells you the definition of epsilon valid that we are using. We track precision, just not in the places that you look for.
We will just remove anything that is smaller than magnitude * 1e-12. With imprecise arithmetic, we have to make tradeoffs regarding precision.
And printing all the z coordinates of the cut vertices shows
0 1.2558103905862674 2.506664671286085 3.747626291714492 4.973797743297096 6.180339887498948 7.362491053693558 8.515585831301454 9.635073482034306 10.716535899579933 11.755705045849464 12.748479794973793 13.690942118573773 14.579372548428232 15.410264855515784 16.18033988749895 16.886558510040302 17.526133600877273 18.096541049320393 18.595529717765025 19.02113032590307 19.37166322257262 19.645745014573773 19.842294026289558 19.960534568565432 20 19.960534568565432 19.842294026289554 19.645745014573773 19.371663222572625 19.021130325903073 18.59552971776503 18.09654104932039 17.52613360087727 16.8865585100403 16.18033988749895 15.410264855515784 14.579372548428228 13.690942118573776 12.748479794973797 11.755705045849465 10.71653589957994 9.635073482034311 8.515585831301458 7.362491053693563 6.18033988749895 4.973797743297096 3.7476262917145005 2.5066646712860905 1.2558103905862716 2.4492935982947065e-15
Where the last coordinate is not 0 or smaller. So the result from manifold is actually more precise. Whether or not it is a better result depends on interpretation.
2 Likes
It’s problem is about fixed point format (double) in Manifold Library.
It’s actually base2 (binary), it can’t represent all fixed point in base 10. (input form human is always base 10)
watch for first 15 mins. it’s enough.
So the calculation is not precise since we use double already.
This why programmer need to deal with them.
Honestly, I have no idea what you are talking about.
Double is floating point, not fixed point. And the issue is not in manifold, but your cut has a 1e-15 gap, so there is a very thin surface left, and it is not due to imprecision in manifold.
Maybe try to check your code before blaming the library from being imprecise?
This is happen even the code isn’t mine.
sebavan
December 18, 2024, 9:43pm
11
Closing the thread as this is all expected and you can pick the CSG engine that leads to the best (subject to interpretation) results.