meshmash / Plankton

A C# half-edge mesh data structure, and components for using this in Grasshopper/Rhino
http://meshmash.github.io/Plankton
GNU Lesser General Public License v3.0
216 stars 66 forks source link

Mesh Operators #3

Closed pearswj closed 11 years ago

pearswj commented 11 years ago

Use this pull request to discuss the new mesh operators, such as edge splits, face splits, edge collapses, etc...

Dan-Piker commented 11 years ago

Their terminology is a bit strange there, but I think one could also say: If the edge is internal, then its ends must not have more than 2 neighbours in common. If the edge is a boundary edge, then its ends must not have more than one neighbour in common.

pearswj commented 11 years ago

That's a better way of looking at it what I was going with. Plus, I think I've found a neat way of implementing that using http://msdn.microsoft.com/en-us/library/bb460136.aspx

pearswj commented 11 years ago

3ae69

Pretty darn robust!

davestasiuk commented 11 years ago

whoa!

On Fri, Aug 30, 2013 at 12:06 AM, Will Pearson notifications@github.comwrote:

[image: 3ae69]https://f.cloud.github.com/assets/121068/1053815/40678e78-10f7-11e3-933b-5a6b7d3b5c8d.gif

Pretty darn robust!

— Reply to this email directly or view it on GitHubhttps://github.com/Dan-Piker/Plankton/pull/3#issuecomment-23527305 .

Dan-Piker commented 11 years ago

Nice! looking solid.

On a somewhat related note. I was looking again at this paper recently: http://research.microsoft.com/en-us/UM/people/yangliu/publication/cmc.pdf

They actually use the appearance of unflippable edges to trigger global topology changes (section 4)

pearswj commented 11 years ago

Hopefully that'll be the last of the edge collapse bugs!!

I noticed that 3+ sided faces have the same effect as boundary edges on the allowed number of shared neighbours.

Also, just a quick note, in your re-meshing script you need to check for the edge collapse returning -1 otherwise it's now giving lots "index out of bounds" errors.

pearswj commented 11 years ago

Nice work on the volume calculation, really handy to have. I think it's probably about time to merge this branch into master. Before doing so though, if you're happy with my latest changes in my fork (i.e. replacing dead items with unset ones) I'll merge that into here first and then we can merge this into master.

Dan-Piker commented 11 years ago

Yes, sounds good. I agree it's about time to merge this.

Dan-Piker commented 11 years ago

It seems 'IsBoundary' isn't working - somehow not all boundary vertices are having their outgoing halfedge set to a boundary halfedge. Maybe something to do with the non-manifold vertex addition ? I'm in 2 minds about whether it is worth keeping IsBoundary, or just giving up the idea of always having the outgoing halfedge be boundary, as one can always check if NakedEdgeCount>0. It does mean more iteration, but is one less thing to have to maintain and check for in all the topology modifiers.

pearswj commented 11 years ago

I never updated your original Rhino mesh to Plankton mesh function to honour the boundary vertex outgoing halfedge condition. Could that be the culprit? Anyway, I'll think of a better reply in the morning!

pearswj commented 11 years ago

image https://www.dropbox.com/s/y46v7jo2nhvum08/boundaryVertices.ghx

pearswj commented 11 years ago

Quoting this directly from our recent discussion to help describe the move to unset items instead of using dead flags. To summarise, making items unset is more deliberate and needs less checking (unset items are traversable, they just don't return anything).

Okay, so, null items are out. But, for future reference they totally work alongside VB's Nothing, in Grasshopper at least, when going from C# to VB (and vice versa).

What I'm currently thinking is that when working with these Euler operators we simply make the dead items unused (or dereferenced from the mesh). That is:

  • a vertex with an outgoing halfedge index of -1;
  • a face with a first halfedge index of -1;
  • a halfedge with a starting vertex index of -1 (adjacent face index should also be set to -1 and next/prev set to pair).

This way, everything works when traversing; an unused vertex has zero vertex neighbours, an unused face has zero sides, etc. Each of these conditions could be encapsulated in a property/method which returns whether or not the item is dereferenced from the mesh – handy for deciding whether to cull the item or not.

In the current set up I definitely don't think that the dead flag should be exposed to the user. It's too easy for an inexperienced user to set a vertex to dead, and then compact the mesh and run into trouble (and not know why!). Working the other way round with the proposed set up I think that someone could fiddle with the references in a bunch of items and knowingly dereference an item from the mesh.