效果展示:
import os
import sys
import json
import argparse
import numpy as np
import pandas as pd
import open3d as o3d
from glob import glob
PARTICLE_RADIUS = 0.025
def stl_to_particles(objpath, radius=None):
if radius is None:
radius = PARTICLE_RADIUS
obj = o3d.io.read_triangle_mesh(objpath)
zhlMoreParticle=1
particle_area = np.pi * radius**2
# 1.9 to roughly match the number of points of SPlisHSPlasHs surface sampling
num_points = int(1.9*zhlMoreParticle * obj.get_surface_area() / particle_area)
pcd = obj.sample_points_poisson_disk(num_points, use_triangle_normal=True)
points = np.asarray(pcd.points).astype(np.float32)
normals = -np.asarray(pcd.normals).astype(np.float32)
outputPLY = objpath+"{:d}.ply".format(num_points)
o3d.io.write_point_cloud(outputPLY,pcd)
print("radius={:}, np={:}".format(radius,num_points))
return points, normals
def points_vtk_output(name, paticle_all):
with open(name, 'w') as fout:
n = paticle_all.shape[0]
fout.write("# vtk DataFile Version 2.0\n\n")
fout.write("ASCII\n")
fout.write("DATASET POLYDATA\n")
fout.write(f"POINTS {n} float\n")
# x
for i in range(n):
fout.write("{:21.14e} {:21.14e} {:21.14e}\n".format(paticle_all['x'][i], paticle_all['y'][i], paticle_all['z'][i]))
fout.write("VERTICES {} {}\n".format(n, 2 * n))
for i in range(n):
fout.write("1 {}\n".format(i))
fout.write("POINT_DATA {}\n".format(n))
# velocity
fout.write("VECTORS velocity float\n")
for i in range(n):
fout.write("{:21.14e} {:21.14e} {:21.14e}\n".format(paticle_all['nx'][i], paticle_all['ny'][i], paticle_all['nz'][i]))
# cell id
fout.write("SCALARS id float 1\n")
fout.write("LOOKUP_TABLE default\n")
for i in range(n):
fout.write("{:d}\n".format(i))
# radius
fout.write("SCALARS radius float 1\n")
fout.write("LOOKUP_TABLE default\n")
for i in range(n):
fout.write("{:21.14e}\n".format(PARTICLE_RADIUS))
points, normals = stl_to_particles('wall.stl')
df_particle = pd.DataFrame(data = np.hstack((points, normals)), columns=['x', 'y', 'z' , 'nx', 'ny' ,'nz'] )
points_vtk_output('wall.vtk', df_particle)