hannesdelbeke / mesh-data-transfer

MeshDataTransfer Blender addon
https://mmemoli.gumroad.com/l/tOKEh
GNU General Public License v3.0
15 stars 3 forks source link

Sometimes vertices receive NaN coordinates during shape transfer. #2

Open izMoff opened 2 months ago

izMoff commented 2 months ago

This happens to me sometimes when i use shape transfer based on UV map, in cases where the mesh is reasonably dense. Some vertices might end up with NaN for coordinates, which effectively makes them disappear from viewport, making it impossible to select and move them manually.

I tried to look at the code myself, and i think the bug occurs somewhere in get_barycentric_coords method, particularly in: main_triangle_areas = np.cross((triangles[:, 0] - triangles[:, 1]), (triangles[:, 0] - triangles[:, 2])) where, i think, some values end up being 0, and then division by 0 ends up happening later down. But i don't really understand this code, and can't fix it myself.

I'll attach a file with two meshes which you can replicate the bug with. example.zip

hannesdelbeke commented 2 months ago

I m on my phone, not at my pc atm.

I see that 4 lines from main triangle area = ...

There is a line that says 'a = ....' A is the surface area of a triangle So if all points are in the same place it can be 0

And then in the next lines we divide by a. So it might be NaN because divide by 0 like you say.

What if you add something after a=... that says

If a == 0:
    a=0.00001

That way we never divide by 0

izMoff commented 2 months ago

Yep, that i did tried. This way, affected verts don't get assigned illegal coordinates, but instead just collapse to some point. At least they can be manually put in place this way, but still.

Although that might be just an issue with these particular models. Now that i actually looked at them closely, UVs in affected areas are a bit of a mess, with overlaps and some of the triangles squished to a line.

Hopefullyidontgetbanned commented 1 month ago

This happens to me sometimes when i use shape transfer based on UV map, in cases where the mesh is reasonably dense. Some vertices might end up with NaN for coordinates, which effectively makes them disappear from viewport, making it impossible to select and move them manually.

I had this issue and it occurs with UV islands that have a size of 0. Very annoying but preventable with documentation.

Prostrelov commented 2 weeks ago

For those who encounter such a problem, there is a way to solve this problem, although not very convenient, but it seems to work. If you have encountered vertexes with “-nan(ind)” as coordinates when shape keys are switched on, try the following:

To understand which areas are not transferred normally we make a temporary duplicate of the geometry “dup_tmp” and transfer all shape keys and drivers to it. Then apply the Subdivision Surface modifier to the object - this will increase the size of holes if they exist. Just in case, we can change the pose a little bit to include more drivers and areas to be included in the deformation. Some areas may not be visible visually. So we go to edit_mode, select all vertexes and try to rotate the viewport. If the viewport flies to the origin or somewhere out in outer space, then the problem areas are present. How to find them not visually is not clear yet, probably we will need a script that will check vertxes for “-nan(ind)” in coordinate values. Now that we know where the problem areas are we create a clean duplicate “dup_tgt” (without vert groups and shape keys) of our target geometry “tgt”. We split all internal parts of the duplicate into a new object “dup_tgt_inners”, because often during the transfer it is with these parts that we have problems due to overlapping geometry. Since on the received geometry there are no inner geometry, they disappear from the shape keys. Now on “dup_tgt” we transfer shape keys from the original geometry “src” through Mesh Data Transfer (Closest). As a result we get shape keys that do not affect the internals. On “dup_tgt_inners” you need to transfer shape keys from the original “src” geometry via Mesh Data Transfer (ActiveUV). ActiveUV mode gives less errors when transferring shape keys for internal geometry, but a lot of errors when transferring shape keys for external geometry. Now. We need to merge two geometries “dup_tgt” + “dup_tgt_inners”. As a result of this merge the shape keys will be merged too ! And only after that we transfer shape keys to “tgt” via Mesh Data Transfer (Closest).

That's quite a lot of manipulation with not always a guaranteed end result. And instead of solving the problem by pressing one button, I had to spend almost a week on inventing such a broken bicycle. The end user doesn't always have the ability to just pick up and edit UV maps. So of course I would like to see some solution to this problem in future versions of this plugin.

Prostrelov commented 1 day ago

I wrote a small addon to fix the problems with -nan(ind) vertexes. It is located on the sidebar under Edit\ShowNanindUsers. The addon goes through all unmuted shape keys and makes a list of problematic vertexes. Reset - assigns coordinates to the vertex from the original geometry coordinates (Basis shape key). Fix - assigns to the vertex an average coordinate from neighboring vertexes from the shape key. You also have an opportunity to put viewport focus on the problem vertex (but for this you will need to temporarily disable all shape keys).

ShowNanindVerts.py