-
Notifications
You must be signed in to change notification settings - Fork 19
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
Surface moments #20
Comments
@devonmpowell @raovgarimella @shevitz |
(copied post from elsewhere) |
(copied from PR thread) |
Or that. For SSD closure, we need the area, but for some other remapping work, we could use the higher moments to compute things at higher order accuracy (in contour integrals). |
And yes, if r3d returned a 2D polygon (in 3D coordinates), then we could transform it to 2D and use r2d to compute moments. That works for me. Similar analogy for clip segment for polygon clipping - return the line segment in 2D and use r1d to compute moments...oh wait! there's no r1d ;) |
One issue for 2D clipping is that you'd somehow need to return multiple segments for non-convex input polygons. In 2D, there can be disjoint polygons connected by a line segment. All the moments are correct. Not sure how to connect two disjoint line segments in one usable data structure. |
I think it's worth taking a look at Koehl 2012 (https://ieeexplore.ieee.org/document/6127882). This is the recursive algorithm used in r3d_reduce. An intermediate step in the derivation is to obtain the surface moments (as a sum of triangles). Then it is extended to 3d by adding the origin as another vertex to make tetrahedra. So it's probably possible to get the 2D moments (embedded in 3D) with a few cleverly-placed lines of code. Then we can just use the face normal to project the moments onto the face itself, without any intermediate r2d step. |
The issue I see is that r3d_poly has no notion of a face unlike r3d_brep. So it is impossible to tell r3d_reduce which face to get moments for. On the other hand, we do have that info when we are clipping or splitting and we throw it away. |
Maybe this ends up being tied to the non-trivalent r3d option and the suggestion to use half-edge data structures. Each half-edge is associated with two faces connected by that half-edge: a previous face and next face. Face ordering could be explicitly defined as part of the half-edge or it might be defined implicitly based on a greedy approach and the half-edge ordering. Half-edge 0 implicitly defines face indexes 0 and 1. Or maybe it only defines face index 0 (it's previous face but not its next). |
Another thought on defining face ids: The input must include one vertex or half-edge associated with each face. For tri-valent polytopes, you have to give one vertex that has the face between its 0th and 1st nodes. For half-edge, you have to give one half-edge that has the face as its "previous" face. Less input data required that way. If you had to define faces for every vertex or half-edge, there would be a lot of redundant data. |
I think the half-edge is worth looking into. |
Is there some advantage that to Half-edge data structures I am missing entirely? Maybe we are talking of entirely different data structures. I knew half-edge data structures from the place they originated (Weiler and Shephard). Each half-edge or edge use only knows about its first vertex use, second vertex use, its previous edge, its next edge and its opposite half edge. Since edge uses are defined by vertex uses, you would have as many vertex uses for a vertex as there are faces coming together at the vertex. Each face is described by a set of ordered half edges. Each solid is described by a set of faces (for non-manifold solids you can actually have half-faces or face uses). The structure was really meant for modeling non-manifold geometric models rather than mesh elements. So, you lose the trivalent vertex structure you have now and you make it a lot more verbose than before. You will be jumping around in memory a lot more and apps will once again spend time converting from BRep to the half-edge data structure and back (same or more cost as init_r3dpoly right now) - this is nearly half of our cost of usage of .R3D. My strong suggestion if you are making the effort to rework the code, work on a straight up BRep data structure. We do it all the time in Portage, Tangram. I use it in MSTK and Jali. It is the most compact representation of a polyhedron that has a notion of faces and vertices. (I have reach far back into my brain, but perhaps FLAG MPygs are also the same?). I would've loved to do this but can't right now. The simple BRep structure that's already in the R3D code is given below. It uses dynamic arrays for now but if you want, you can convert it to use static arrays. If you need to, you can devise one that explicitly represents edges.
The static version can look like
R3D_MAX_FACES can be same as R3D_MAX_VERTS (since you won't be proliferating vertices by enforcing the trivalent condition) |
As for the original topic of surface moments, I interpreted Mack's original query as wanting the moments of the clip face or the face between the two halves. My suggestion there is to hew close to what I floated earlier. Let the R3D clip and split routines just give you a R2D poly that you can call R2D_reduce on. |
Hmm, this is definitely true about jumping around in memory. The half-edge is more of a linked list than anything else. One other questions about projecting faces into 2D is, does it matter what the x-y orientation is on the original face? |
I vote for Devon trying out the half-edge approach and maybe comparing performance to the current version. It sounds like he's been thinking about it and is ready to go for it. There are issues with the current version and there are at least two proposed solutions, each certainly with pro's and con's. Until/unless someone tries both out or does a methodical on-paper evaluation of pro's and con's, we won't know which solution is superior. My guess is that both solutions will be slower and/or use more memory in certain cases and a "winner" will be subjective (for example, I don't care about an increase to R3D_MAX_VERTS). |
I'd also like to ask a philosophical question about r3d. On one hand, every option could be implemented via some function. R3d could support trivalent, half-edge and brep. It could offer dynamic and static allocation options. On the other hand, one "compromise" set of functions could be provided that is sufficiently general. The first option is harder to maintain has a more complicated API but is completely flexible and probably offers the best possible performance in the most use cases. The other option is easier to maintain, is simpler to use, but will probably be the least performant. I'm curious what your opinions are on this. |
FYI, we've ported r2d/r3d to modern fortran for our project (so that we can easily pass around polytopes on the fortran side of things in our fortran host code and get things to perform on GPUs) and have done a lot of extending. We added a non-trivalent type (which is 2.5x faster on our polytopes) in addition to tri-valent (can use either). We've added the ability to optionally return the clip face that results from clipping (r3d_clip optionally returns an r3d_polygon type and r2d_clip returns an r2d_line type). We've added the ability to compute moments on these degenerate types (moments of r3d_polygon and r2d_line types). We will probably also add the ability to linearly interpolate polytope vertex fields (interpolate edge endpoint values to the clip vertex as each edge is clipped). There was a bit of debate about how to implement all of this. I'm guessing it would be a similar situation for C or C++. |
Very nice, Mack. |
Because all new vertexes are added on the perimeter of the polytope and always at edges, I believe that edge interpolation would produce the same result as tetrahedralization and linear barycentric interpolation. As for hexes, you could certainly do something more exotic/accurate. Currently, I'm just thinking about using this for visualization purposes where we have clipped-up a multi-material cell into pure sub-pieces and want to provide smooth-looking solutions near material interfaces, so it's more qualitative. Any actual remapping we do relies on exact volume integrals via moments. |
Cool! It sounds totally sufficient for your purposes. |
No description provided.
The text was updated successfully, but these errors were encountered: