rnd-team-dev / plotoptix

Data visualisation and ray tracing in Python based on OptiX 7.7 framework.
https://rnd.team/plotoptix
Other
499 stars 26 forks source link

mesh smoothening not working #18

Closed sarangzambare closed 3 years ago

sarangzambare commented 3 years ago

Hi!

First of all amazing work making this library! :)

I am trying to load an obj file using load_merged_mesh_obj. My obj file is Desk, and the legs of the desk are cylindrical.

I tried loading the obj file in three ways:

  1. using make_normals = True
  2. using make_normals = False
  3. parsing the obj file for normals -> creating a normals array -> feeding that normals array to the mesh using update_mesh

However, I observe no change in the way the object is rendered, the legs of the desk still look jagged. Attaching pictures from the three cases:

case1: mntrue

case2: mnfalse

case3: normalsprovided

My questions are:

  1. Is this expected behavior?
  2. If yes, is there any API I can use to smoothen the edges?
  3. Do we have control over the smoothing angle used to smoothen surfaces?

Thanks! :) Here's my source code:

import numpy as np
from plotoptix import TkOptiX
from obj_parser import get_uvmap
from plotoptix.materials import m_diffuse

def main():

    obj_file = "Desk.obj"
    texture_file = "Desk_AlbedoTransparency.png"
    rt = TkOptiX()
    rt.set_param(max_accumulation_frames=500)
    rt.set_background(0)

    # rt.setup_light("light1", pos=[10, -9, -8], color=[9, 8, 7], radius=4)
    rt.set_ambient([0.7, 0.8, 0.9])

    uv_map, normal_map = get_uvmap(obj_file)
    rt.load_merged_mesh_obj(obj_file, 'desk')

    #case3
    rt.update_mesh('desk', c=1, uvmap=uv_map, normals=normal_map)

    rt.load_texture('desktexture', texture_file)
    m_diffuse["ColorTextures"] = ["desktexture"]
    rt.update_material("diffuse", m_diffuse)

    rt.setup_camera("cam1")
    rt.get_camera_target()
    d = np.linalg.norm(rt.get_camera_target() - rt.get_camera_eye())
    rt.setup_light("light1", color=[9, 8, 7], radius=0.3 * d)
    rt.show()

if __name__ == "__main__":
    main()
robertsulej commented 3 years ago

Hi Sarang,

Can you share the mesh? I can have a look at it.

I just have tried with the attached obj file containing mesh with no stored normals and this example, loading the mesh with both load_mesh_obj() and load_merged_mesh_obj() functions, and make_normals seems working.

Maybe faces in your mesh are not sharing vertices?

You can also inspect what exactly is stored in the vertex, normals, etc buffers: see this example and docs (this API is evolving, but already quite usable).

utah-teapot_no_normals.zip

sarangzambare commented 3 years ago

Hi,

This is weird, with the teapot obj file that you linked, the make_normals seems to be working. However it does not work with my Desk.obj file, I am attaching the file here.

Some differences that I see between my obj file and the teapot one are :

  1. In Desk.obj the faces are given in the format = v_index/vt_index/vn_index In teapot obj file the faces are given in the format = v_index only

    e.g f 1/1/1 4/4/4 2/2/2 vs f 1 5 6

  2. The teapot obj file has an s off flag in it just before starting the faces

I am now trying to further inspect the objects using the PinnedBuffer API that you linked earlier, but please let me know if my Desk.obj file works for you.

Desk.zip

robertsulej commented 3 years ago

The difference in face format is because there are no normals and no uv mapping in the file I have sent.

Normals in your file look correct if I load it into Blender. Later today I'll try to understand what is going on.

If I remove normals from Desk.obj, and re-calculate them with make_normals=True, then the mesh looks correct. The file is attached. desk_no_normals.zip

I also tried removing uv's and export only positions and normals to obj - I think there is a bug in loading obj with this combination.

I'll let you know when I find fixes.

robertsulej commented 3 years ago

OK, I checked the loading code and it is correct. So also in the case when uv's are not present everything is OK.

Loading the obj file works in the way that if there are normals present in the file already, it does not re-calculate them, even if make_normals=True.

I took a closer look at the normals in your file using Blender. Looks like they are all OK, but shading is a bit strange. So I did "reset vectors", which helped, and exported such file. Then in plotoptix things look OK as well.

desk

I don't know what was the problem with normals. Vectors didn't move visually when I reset them.

Corrected obj attached.

desk_reset.zip

sarangzambare commented 3 years ago

Hi,

That's interesting and weird haha. I also tried removing all the normals from the obj file and the make_normals=True did make a difference but the smoothening was not very fine (I could still see jagged lines, just not as much as with normals).

Thanks for trying out Blender and attaching the file. I will perhaps add that step into my pipeline as well.

I think the best course of action from this issue would be to update the documentation regarding make_normals ? Thanks anyway! :)

closing this issue.

sarangzambare commented 3 years ago

make_normals=True calculates normals only when no normals are provided in the OBJ file.

robertsulej commented 3 years ago

Yes, I'll add that to docs, thanks!