OpenDroneMap / Obj2Tiles

Converts OBJ files to OGC 3D tiles by performing splitting, decimation and conversion
GNU Affero General Public License v3.0
214 stars 62 forks source link

Exception: Invalid texture coordinates: (0.017; -0.0634) #35

Open Franz362100 opened 1 year ago

Franz362100 commented 1 year ago

I used the obj data exported by 3dmax, and the following error occurred.

!> Exception: Invalid texture coordinates: (0.017; -0.0634)

STILLMOREzzz commented 1 year ago

I have also encountered a similar problem, which is caused by the use of udim. I still don't know how to deal with this problem. !> Exception: Invalid texture coordinates: (2.6630 0.2584)

phoenixbf commented 1 year ago

Hi, I have encountered the same problem. Maybe a possible fix could be clamping the uv coords parsed in Obj2Tiles.Library/MeshUtils.cs in [0,1]?

if (vtx.X < 0 || vtx.Y < 0 || vtx.X > 1 || vtx.Y > 1)
  throw new Exception("Invalid texture coordinates: " + vtx);
phoenixbf commented 8 months ago

any updates? The process completely stops on several OBJs. Maybe it is sufficient to clamp uv coords instead of halting completely the process

yashchauhan28 commented 1 month ago

This error is due to non-normalized UV coordinates. You can create a custom script or use Blender for this.

pronitdas commented 1 month ago

`import bpy

def normalize_uvs(mesh): print(f"Processing object: {mesh.name}")

# Ensure the object is in object mode
bpy.ops.object.mode_set(mode='OBJECT')

# Get the UV layer
if mesh.data.uv_layers.active is None:
    print(f"No UV map found for object {mesh.name}")
    return

uv_layer = mesh.data.uv_layers.active.data

# Calculate the bounds of the UV coordinates
uvs = [uv.uv for uv in uv_layer]
min_uv = uvs[0].copy()
max_uv = uvs[0].copy()

for uv in uvs:
    min_uv.x = min(min_uv.x, uv.x)
    min_uv.y = min(min_uv.y, uv.y)
    max_uv.x = max(max_uv.x, uv.x)
    max_uv.y = max(max_uv.y, uv.y)

print(f"Min UV: {min_uv}, Max UV: {max_uv}")

# Calculate the scale to normalize the UVs
uv_scale = max_uv - min_uv

for uv in uvs:
    uv.x = (uv.x - min_uv.x) / uv_scale.x
    uv.y = (uv.y - min_uv.y) / uv_scale.y

print(f"UVs normalized for object {mesh.name}")

Loop over all selected objects

for obj in bpy.context.selected_objects: if obj.type == 'MESH': normalize_uvs(obj)

print("UV normalization complete.") `

used this to get away with the error. but the textures messed up a bit.