-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't simplify unless requested #1185
base: master
Are you sure you want to change the base?
Conversation
btw this may be related to simplification: openscad/openscad#5738 |
const int numProp = std::max(inP_.NumProp(), inQ_.NumProp()); | ||
if (numProp > 0) { | ||
// Ideally, switch over from triProperties vec to Halfedge.startProp - then | ||
// the prop index will be available in the append edges functions below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pca006132 I'm struggling to get this one finished - are you interested in taking a look? If you look at my last commit, I've added comments on the refactor I have planned. I think it's pretty straight forward, and I bet you'd optimize it better than I would.
I ask because this is probably the last major PR to land before doing a release, right? We have a lot of good stuff now (mostly yours) and I don't want to delay it. Let me know what you think - and is my description clear at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can have a look at it later tonight.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is kind of similar to what CreateProperties is doing, but you want to do it in parallel, and probably handle edges differently?
About the inclusion number array, should it be indexed by the vertex id, halfedge id, prop vert id or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, index by prop vert. Every prop vert has exactly one vert, so that makes things nice. The idea is to keep track of properties directly by index just like the verts, instead of needing to look anything up with maps or hash tables.
I still have several high-level questions about how properties work, but I am getting there. First, to make sure I understand this correctly, a prop vert is What we want to do here is to
What I understand from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made separate threads to answer each of your questions.
// | ||
// New verts create either 2 or 3 new properties: one for the face, plus one | ||
// for an edge where start and end verts share properties, or plus two for | ||
// an edge that doesn't share both properties. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the answer to question 2-i. It might be clearer if I said "prop verts" instead of "properties" - that's what I mean.
for (const int i : {0, 1, 2}) { | ||
prop2VertP[inP_.meshRelation_.triProperties[tri][i]].store( | ||
inP_.halfedge_[3 * tri + i].startVert); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another piece of 2-i: No - every propVert maps to exactly one vertex, hence this vector being possible. Whenever the same value shows up multiple times in this list, that's a vertex that's associated with multiple propVerts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an important feature (because it's also implicitly a restriction in MeshGL), so to answer question 1 - we definitely need to duplicate rather than reuse the index. Again, this duplication is actually exceedingly rare in practice since it's only for handing self-intersecting meshes.
// | ||
// Copy included inP and inQ properties to outR, and duplicate for new verts | ||
// accoding to the inclusion numbers. Calculate new outR properties using | ||
// the Barycentric function from CreateProperties. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 2-iii: It's best to think of propVerts as being on a halfedge or triangle - the paired halfedge usually, but doesn't always, shares the same propVerts. Only if both ends of the paired halfedges share propVerts can you interpolate that as a single new shared propVert - otherwise you'll be creating two new propVerts, one for each halfedge. It's not possible to have two ends of the same halfedge have properties that don't represent the same channels of data. The channels of data are consistent across each meshID, or equivalently, each triangle run in MeshGL. So they are also consistent over a triangle or halfedge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you define what share propVerts means? If each propVert maps to exactly one vertex.
And for these new vertices, where do their propVerts come from? Say, if each vertex of the associated triangle originally maps to 2 propVert, we should have 2 propVert interpolated using barycentric coord, plus some propVerts interpolated using propVerts associated to endpoints of the edge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By share propVerts, I mean the paired halfedges point to the same prop index. Basically verts must be manifold, while propVerts may be manifold. The edge is prop-manifold if the propVerts are shared.
The second part isn't quite right. Any given triangle only has one set of three propVerts; new propVerts on either its edges or its center all get interpolated barycentricly using that single interpolant. So e.g. 6 triangles ajoin a vertex - this vertex might have 2 propVerts, meaning e.g. 3 of those triangles point to one propVert and 3 point to the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If two paired halfedges (with different starting vertices) can point to the same prop vert, what does it mean by each prop vert maps to one vert?
Or does this mean each prop vert maps to one edge (can be one or two halfedges)?
// an edge that doesn't share both properties. | ||
// | ||
// Copy included inP and inQ properties to outR, and duplicate for new verts | ||
// accoding to the inclusion numbers. Calculate new outR properties using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 2-ii: Yes, we copy all retained propVerts, just like we do verts. But the number isn't going to explode any more than the number of verts does. Well, technically you'll get double the number of new propVerts as new verts, but considering in general I think of these problems as scaling such that the number of new verts is O(sqrt(n)) for n: the number of input verts, I don't think that's a huge problem. Plus it's fundamentally necessary in order to represent e.g. UV coordinates.
}); | ||
// Scan the properties inclusion numbers, e.g. + i03[prop2VertP[prop]]. | ||
// | ||
// New verts create either 2 or 3 new properties: one for the face, plus one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also, how are these new prop verts computed and attached to halfedges?
For the face prop vert, it is barycentric interpolation from the three prop vert of the intersecting face, but which new halfedge to attach to?
For prop vert corresponding to an edge (two different cases), how should we interpolate them and where should we attach the prop vert to?
Sorry for a lot of questions, it may be easier for you to directly implement it rather than explaining them.
Fixes #1138 - really that thread, while interesting, has grown way too long and gone on too many tangents. Some has already been fixed, this fixes some more - please make separate issues for whatever's left.
Now that #1147 has landed which makes the Boolean only decimate the intersected parts of meshes, this PR finishes the job by removing our auto-decimation from the rest of our functions, so users can just call it manually if they want through
Simplify
. I've also deprecated thecleanupTriangles
option, since it's effectively always false now. We're still collapsing degenerate triangles and fixing topology at the epsilon level, but not touching colinear edges, coplanar faces, or anything that's only within tolerance. @stephomi, @starseeker, @howardt I believe you all may have asked for things along this line at various points, so it would be great to have some early eyes on this and get feedback.Good new / bad news is this improved our testing and thus found that
Simplify
doesn't handle properties correctly at all. It looks like I now need to add a significant refactor here to fix that, but on the plus side I think I can remove ourCreateProperties
function entirely, which has gone through quite a bit of optimization due to slowing things down a lot in the past. I think I have a cleaner way now.