ms.compute_normal_per_vertex IGNORED
TokyoWarfare opened this issue · comments
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