f1shel / pyatlas

python wrapper of microsoft UVAtlas
MIT License
3 stars 0 forks source link

About the speed #1

Open seed93 opened 2 months ago

seed93 commented 2 months ago

Have you tested the speed? It run over 30 seconds for a 10k vertices mesh, which is abnormal compared with open3d. I checked it was compiled with openmp. Thank you. It is a great work.

f1shel commented 2 months ago

Oooops, I have encountered similar issues actually. This package seems much slower than other UV unwrapping libraries. I mainly followed the logic in UVAtlas.cpp, eliminating all optional branches. Could you please run the official Microsoft UVAtlasTool on the same mesh and let me know how long it takes?

seed93 commented 2 months ago

Oooops, I have encountered similar issues actually. This package seems much slower than other UV unwrapping libraries. I mainly followed the logic in UVAtlas.cpp, eliminating all optional branches. Could you please run the official Microsoft UVAtlasTool on the same mesh and let me know how long it takes?

I didn't try the official tool, but it is much faster as far as I know. If it was me to debug, I would profile which part is most time consuming. I guess it only uses one cpu core to compute while openmp is enabled. Also maybe there are some optimization methods not suitable for linux.

seed93 commented 2 months ago

https://github.com/isl-org/Open3D/blob/main/cpp/open3d/t/geometry/kernel/UVUnwrapping.cpp in open3d, it use multithread above uvatlas. Maybe it is the key point.

f1shel commented 2 months ago

Oooops, I have encountered similar issues actually. This package seems much slower than other UV unwrapping libraries. I mainly followed the logic in UVAtlas.cpp, eliminating all optional branches. Could you please run the official Microsoft UVAtlasTool on the same mesh and let me know how long it takes?

I didn't try the official tool, but it is much faster as far as I know. If it was me to debug, I would profile which part is most time consuming. I guess it only uses one cpu core to compute while openmp is enabled. Also maybe there are some optimization methods not suitable for linux.

Thank you for the feedback :] Sorry that I'm a bit busy with my paper right now. I estimate I will have time to look at this bug in a few weeks. I'll look into it right away as soon as I have some free time.

seed93 commented 1 month ago

It seems we need a pcapartition and then process parallely. https://github.com/isl-org/Open3D/blob/main/cpp/open3d/t/geometry/kernel/PCAPartition.cpp

Will you improve this?

f1shel commented 2 weeks ago

It seems we need a pcapartition and then process parallely. https://github.com/isl-org/Open3D/blob/main/cpp/open3d/t/geometry/kernel/PCAPartition.cpp

Will you improve this?

I'll take a look. I have also noticed that the parameter parallel_partitions in open3d.cpu.pybind.t.geometry.TriangleMesh.compute_uvatlas significantly affects the speed of UV mapping. However, it's strange that I can't seem to get the correct UV partitions when using it. Download bunny.obj here.

import open3d as o3d
import numpy as np
import trimesh
import time

mesh = trimesh.load('bunny.obj', process=False, force='mesh')

o3d_mesh = o3d.t.geometry.TriangleMesh()
o3d_mesh.vertex.positions = o3d.core.Tensor(mesh.vertices)
o3d_mesh.triangle.indices = o3d.core.Tensor(mesh.faces)

t1 = time.time()
o3d_mesh.compute_uvatlas(size=1024, gutter=10, parallel_partitions=4)
print("Time:", time.time() - t1)

# since in open3d uv is defined on triangles, we need to rearrange vertices
new_v = mesh.vertices[mesh.faces.reshape(-1)]
new_f = np.arange(len(new_v)).reshape(-1,3)
new_uv = o3d_mesh.triangle.texture_uvs.numpy().reshape(-1,2)

mesh = trimesh.Trimesh(
    vertices=new_v,
    faces=new_f,
    process=False, # !important
)
mesh.visual = trimesh.visual.TextureVisuals(
    uv=new_uv.astype(np.float32), 
)
ret = mesh.export('bunny.uv.obj')

image

f1shel commented 2 weeks ago

It seems we need a pcapartition and then process parallely. https://github.com/isl-org/Open3D/blob/main/cpp/open3d/t/geometry/kernel/PCAPartition.cpp Will you improve this?

I'll take a look. I have also noticed that the parameter parallel_partitions in open3d.cpu.pybind.t.geometry.TriangleMesh.compute_uvatlas significantly affects the speed of UV mapping. However, it's strange that I can't seem to get the correct UV partitions when using it. Download bunny.obj here.

import open3d as o3d
import numpy as np
import trimesh
import time

mesh = trimesh.load('bunny.obj', process=False, force='mesh')

o3d_mesh = o3d.t.geometry.TriangleMesh()
o3d_mesh.vertex.positions = o3d.core.Tensor(mesh.vertices)
o3d_mesh.triangle.indices = o3d.core.Tensor(mesh.faces)

t1 = time.time()
o3d_mesh.compute_uvatlas(size=1024, gutter=10, parallel_partitions=4)
print("Time:", time.time() - t1)

# since in open3d uv is defined on triangles, we need to rearrange vertices
new_v = mesh.vertices[mesh.faces.reshape(-1)]
new_f = np.arange(len(new_v)).reshape(-1,3)
new_uv = o3d_mesh.triangle.texture_uvs.numpy().reshape(-1,2)

mesh = trimesh.Trimesh(
    vertices=new_v,
    faces=new_f,
)
mesh.visual = trimesh.visual.TextureVisuals(
    uv=new_uv.astype(np.float32), 
)
ret = mesh.export('bunny.uv.obj')

image

I've identified the bug: it's important to remember to pass process=False when initializing a trimesh.Trimesh. Now, the issue is that I wasn't aware Open3D already has a similar UVAtlas tool when I initially wrapped this package. After some testing, I found that Open3D performs better, although it requires several rounds of conversion. Given this, is it still necessary to update this repository?

image