← All ideas
  • Published 31 May 2020

Idea of a auto-retopology algorithm

This one is an idea I had for a possible multithreaded bakeable auto-retopology algorithm.

The main goal of this post is for people to try to highlight as many problems as this algorithm can encounter, or point out if there is already another better solution i don't know about :))

The algorithm is explained as pseudo-code with images, as I tried to make it as easy to understand as possible, but there is my personal opinion on the approach too

Notes:

  • When I talk about "cubes" i mean voxels; however, I think that way it is easier to visualize even if you don't understand voxels.
  • There are three sets of images, the first one has a easy topology on a character's arm, the second one has a more difficult topology on a plane. The last one has a finger-like terrible topology with a gap in it.
  • There is no implementation of the algorithm, and the images were made by hand-modeling the interaction of the algorithm to the environment. The results may vary, if i'm in the wrong
  • Non-connected edges means there is no direct path through the face that also doesn't go through a seam

#########

ALGORITHM

#########

Make a cube grid along the mesh of the model, the size of them being inverse proportion of vertex density times a constant (resolution chosen by user)

image

0 < t <= number of threads

Choose t of the cubes, project it to the mesh in a way that you get a single plane (skinwrap modifier-like projection) and (multithread lock) lock them as a in-use resource, assign them to a cube from the grid .

image image image

In the first iteration the grid can be moved to match better the first created plane

Now starts a loop that can be multithreaded:
For every edge of the original mesh that intercepts the plane:  get the vector of the edge, and record it. All vectors will be used as to determine were the face/faces should be extruded to

image

image

image

image My approach would be to hash the xyz direction of the vector into a hashmap/array of 6 pre-defined groups (+x, -x, +y, -y, +z, -z) and make the arithmetic mean of the vectors that land in each position (And therefore you need to keep track of how many vectors you have stored). This mean, together with the vector of the edge being extruded gives the program where to place the new edge. Also, if there is too much difference between two oposite axis, it means there is a split in the edge flow, and it should spawn two faces instead of only one

&emsp;If two vertex have no direct path trough the plane: &emsp;.&emsp;split the cube into smaller cubes, leaving the non-connected sub-groups in these smaller cubes, and leave those cubes for later iterations

image

image

image

Once done, for each non-connected edge of the final mesh's edges, check every neighbour cube:

If it already has a face:  . If the angle between the calculated vector and the ocupied face's closest edge is big enough (i guess greater than around -20º):  . . extrude a new face

&emsp;.&emsp;.&emsp;If the angle is not too big (i guess less than around 20º): &emsp;.&emsp;.&emsp;.&emsp;connect the adjacent edges

. . Otherwise:

&emsp;.&emsp;.&emsp;.&emsp;If the distance between the edges is too small: &emsp;.&emsp;.&emsp;.&emsp;.&emsp;merge them at center &emsp;.&emsp;Otherwise: &emsp;.&emsp;.&emsp;create a new face from the two edges &emsp;Otherwise, if there is no face nearby: &emsp;.&emsp;Extrude the face along the calculated edge

image

image This picture ends up with a non-desirable topology because of the edge flow. It could be an option to check for curvature in the mesh before extruding it curved image
Once you have a face created: unlock the in-use cube lock the nearest cube assign the new created face to that nearest cube

`

Repeat the loop until completion

image

image

image

image

image

image

Pseudo-code (no images) pastebin.com/cU7e5zKv

In my opinion this algorithm is good because:

  • It can be multithreaded easily
  • Generates mostly quads
  • Follows the flow of the edges
  • Can be set to depend on vertex denisty
  • Although it may need auxiliar voxel remeshing, once you've got the grid it should work in planes and non-waterproof meshes
  • Linear in complexity
  • Hard edges may be faked with seams
  • It can be "baked" meaning you'd only have to update modified vertices, which maybe can become a real-time auto-retopology tool

And also has its drawbacks

  • It does need to have three meshes, which may lead to high ram usage
  • It tends to generate tris around hard edges
  • Although it is linear in complexity, it needs to iterate over a lot of edges

Thank you for reading this

100%

Development Status: Open

Upvote 6 Downvote 0
saisua
31 May 2020

3 Comments

LapisSea

An interesting approach to auto re-topology for sure!

I think a major problem with your approach is the reliance on the base mesh topology. A good retopology algorithm must be able to work on all kinds of meshes. (4 good examples are: heavily decimated mesh, OpenVDB remesh result, photo scans, unoptimal multiresolution) In the best case scenario an algorithm would output the exact same mesh no matter how you change the topology of a surface as long as you do not change the shape)

To reduce this issue you could replace working on input edges with surface walking. (if you wish to place an edge, you sort of think about the base mesh as a 2d surface and you move on it until you for example achieve a desired distance from start)

Also instead of placing quads one by one you could think of each vertex as a magnet that repels away from vertices near it. Then after you evened out the vertices you just need to connect them by edges and fill out the faces.

Also here are some things that I can think of that a good algorithm can handle. I find it useful to think about this things when creating a topology algorithm.

  • Sharp edges (essential for hard surface retopology)
  • boarder freezing (keep exact edges that are at the end of surface)
  • Mirror awareness
  • Local density (you want more density around a finger or eyes than around a leg)
  • Handling non manifold geometry
  • Curvature/surface roughness that changes the topology flow/density
  • Loopcut friendly generation. An edge will try to not spiral all around a model but be contained to some area like an arm. (very hard. Even Exoside QuadRemesher has very bad problems with this i.imgur.com/wMIf89T.png )
  • Good course mesh generation but also re flowing (re flowing aka keeping the amount of original topology and only fixing the flow of edges and density)
  • User inputs such as guides or strictly defined edge lines (see instant meshes as an example) or topology areas. (polygroups in zbrush)
  • Auto complete (Take an unfinished manual re topology and finish the job while adapting to the already existing topology)
  • Special effects such as placing support edges on sharp surfaces or creating bezier surface that imitates normal shading

Also useful food for thought: youtube.com/watch

1
saisua Author

* @Lapis Sea * You are right, I can see it making a mess with photo-scans or high density, pointy meshes.

Also, it could give different results even with the same mesh with no changes (The algorithm heavily depends on the starting point)

Based on your comment, I've seen one problem I think I can improve, and I have also seen some more problems it cannot solve right now.

The thing I think I can improve is tris around hard edges. By tracing hard edges with quads at the beggining (from sharper angle to softer) you could have less tris. The angles would be decided from the base mesh and the generated cube grid (to detect high density corners). After that step, the algorithm could be used to fill out the mesh

But the issues still remain

  • Edge spiraling
  • Different mesh from same shape
  • Differentiating high density detail from dispensable high density mesh parts
  • Pointy/Noisy meshes
  • Weird-ended hard edges could introduce tons of artifacts if not low enough resolution


Also I have one doubt, regarding the "mirror awareness" point. Do you mean to take input from an external source that tells you if there is any mirroring (like a boolean given from Blender, pex) or for the algorithm to detect mirroring? The algorithm would need a lot of improvements to being useful, but I think I'll keep thinking about it in case I can come up with something

(Specially the edge spiraling one I had totally forgotten about looks to me like a fun hard puzzle to think about)

Thank you very much for your comment, I have so much reading to do :D

If I were to think of anything else, I will post it

LapisSea

* @saisua * Oh sorry I should have explained the mirror awareness. Basically, instead of needing to bisect the model and remesh that the algorithm should know to take in to account only half of the mesh what will almost always create nicer topology due to extra context given.

Quadriflow example:

i.imgur.com/esESa21.png

i.imgur.com/mHJcCK0.png