Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ms.compute_normal_per_vertex IGNORED #372

Open
TokyoWarfare opened this issue Jun 2, 2024 · 0 comments
Open

ms.compute_normal_per_vertex IGNORED #372

TokyoWarfare opened this issue Jun 2, 2024 · 0 comments

Comments

@TokyoWarfare
Copy link

TokyoWarfare commented Jun 2, 2024

Hi, I've the feeling that the

"ms.compute_normal_per_vertex(weightmode=1)" command is not working.

I tested in in UI version, works great, removes all the here and there faces that are not properly oriented. I generated the pymeshlab with the super convienent button that builds up the command.

But the thing is that the output mesh seems unprocesed, and if I open in UI version and run the command manually via interface all the issues are fixed.

Here is the whole script

`import os
import pymeshlab

input_folder = r'E:\LIDAR_JAPAN\MMS_14_Prototype_4\MMS\04_RoadMesh\04_Texturing\01_DATA_SOURCE_POINT_CLOUDS\00_color'
output_folder = r'E:\LIDAR_JAPAN\MMS_14_Prototype_4\MMS\04_RoadMesh\04_Texturing\01_DATA_SOURCE_POINT_CLOUDS\03_Normals\HD_RoadMesh'
depth = 13

print(f"Input folder: {input_folder}")
print(f"Output folder: {output_folder}")
print(f"Depth value: {depth}")

def compute_average_normal(ms):
normals = ms.current_mesh().vertex_normal_matrix()
avg_normal = normals.mean(axis=0)
return avg_normal

def mesh_point_clouds(input_folder, output_folder, depth):
if not os.path.exists(input_folder):
raise FileNotFoundError(f"The input folder '{input_folder}' does not exist.")

if not os.path.exists(output_folder):
    os.makedirs(output_folder)
else:
    print(f"Output folder '{output_folder}' already exists. Files may be overwritten.")

files = [f for f in os.listdir(input_folder) if f.endswith('.ply')]
total_files = len(files)
print(f"Total files to be processed: {total_files}")

for i, file in enumerate(files, 1):
    input_path = os.path.join(input_folder, file)
    output_path = os.path.join(output_folder, file)
    
    print(f"[{i}/{total_files}] Loading file: {file}")

    ms = pymeshlab.MeshSet()
    ms.load_new_mesh(input_path)
    
    # Compute normals for the point cloud
    print(f"[{i}/{total_files}] Computing normals for: {file}")
    try:
        ms.compute_normal_for_point_clouds(k=20, smoothiter=0)
    except pymeshlab.PyMeshLabException as e:
        print(f"Failed to compute normals for {file}: {e}")
        continue
    
    # Perform surface reconstruction
    print(f"[{i}/{total_files}] Generating surface reconstruction for: {file}")
    try:
        ms.generate_surface_reconstruction_screened_poisson(depth=depth)
    except pymeshlab.PyMeshLabException as e:
        print(f"Failed to process {file}: {e}")
        continue
    
    # Delete input point cloud to force normal computation on the mesh
    #os.remove(input_path)

    # Print number of faces before recomputing normals
    num_faces = ms.current_mesh().face_number()
    print(f"[{i}/{total_files}] Number of faces before recomputing normals: {num_faces}")

    # Recompute normals for the reconstructed mesh
    print(f"[{i}/{total_files}] Recomputing normals for: {file}")
    try:
        ms.compute_normal_per_vertex(weightmode=1)
    except pymeshlab.PyMeshLabException as e:
        print(f"Failed to recompute normals for {file}: {e}")
        continue
    
    # Check the average normal direction
    avg_normal = compute_average_normal(ms)
    if avg_normal[2] < 0:  # If the z-component is negative, normals are pointing downwards
        print(f"[{i}/{total_files}] Inverting normals for: {file}")
        try:
            ms.meshing_invert_face_orientation()
        except pymeshlab.PyMeshLabException as e:
            print(f"Failed to invert normals for {file}: {e}")
            continue
    
    # Save the mesh
    ms.save_current_mesh(output_path)
    
    print(f"[{i}/{total_files}] Processed {file} and saved to {output_path}")

mesh_point_clouds(input_folder, output_folder, depth)
`

I've uploaded a sample input file
https://drive.google.com/file/d/1RzwmuURgNsWdC3FUmrXaRfOUxQVictP-/view?usp=sharing

I would love to heard wetehr this is the case or it is me that I'md doing something wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant