Source code for svcco.implicit.load
import numpy as np
import vtk
import os
from vtk.util import numpy_support
from ..utils.remeshing.remesh import remesh_surface
import pyvista as pv
[docs]def load3d(filename,subdivisions=0):
vtk_reader = {'stl':vtk.vtkSTLReader,
'obj':vtk.vtkOBJReader,
'ply':vtk.vtkPLYReader,
'vtu':vtk.vtkXMLUnstructuredGridReader,
'vtp':vtk.vtkXMLPolyDataReader,
'3ds':vtk.vtk3DSImporter}
ext = filename.rsplit('.')[1].lower()
if ext not in vtk_reader.keys():
print('Not a supported 3D file format')
print('Supported Formats:\n{}'.format([supported_ext + '\n' for supported_ext in vtk_reader.keys() ]))
return
reader = vtk_reader[ext]()
reader.SetFileName(filename)
if ext == '3ds':
reader.ComputeNormalsOn()
reader.Update()
elif ext == 'vtu':
pass
else:
reader.Update()
data = reader.GetOutput()
points = data.GetPoints()
points = points.GetData()
points = numpy_support.vtk_to_numpy(points)
data_normals = data.GetPointData()
normals = data_normals.GetNormals()
if subdivisions > 0:
linearSubdivision = vtk.vtkLinearSubdivisionFilter()
linearSubdivision.SetNumberOfSubdivisions(subdivisions)
linearSubdivision.SetInputData(data)
linearSubdivision.Update()
data = linearSubdivision.GetOutput()
points = data.GetPoints()
points = points.GetData()
points = numpy_support.vtk_to_numpy(points)
normals_gen = vtk.vtkPolyDataNormals()
normals_gen.SplittingOn()
normals_gen.ComputeCellNormalsOff()
normals_gen.ComputePointNormalsOn()
normals_gen.SetInputData(data)
normals_gen.Update()
normal_polydata = normals_gen.GetOutput()
normal_point_data = normal_polydata.GetPointData()
normals = normal_point_data.GetNormals()
normals = numpy_support.vtk_to_numpy(normals)
else:
#normals = numpy_support.vtk_to_numpy(normals)
if normals is None:
"""
normals_gen = vtk.vtkPolyDataNormals()
normals_gen.SplittingOn()
normals_gen.ComputeCellNormalsOff()
normals_gen.ComputePointNormalsOn()
normals_gen.SetInputData(data)
normals_gen.Update()
normal_polydata = normals_gen.GetOutput()
normal_point_data = normal_polydata.GetPointData()
normals = normal_point_data.GetNormals()
normals = numpy_support.vtk_to_numpy(normals).tolist()
points = []
norms = []
for idx in range(normal_polydata.GetNumberOfCells()):
tri = normal_polydata.GetCell(idx)
tri_points = numpy_support.vtk_to_numpy(tri.GetPoints().GetData()).tolist()
points.extend(tri_points)
for jdx in range(len(tri_points)):
norms.append(normals[idx])
"""
obj = pv.PolyData(var_inp=data)
obj = obj.compute_normals()
#points = np.array(points)
#normals = np.array(norms)
points = obj.points
normals = obj['Normals']
else:
normals = numpy_support.vtk_to_numpy(normals)
upt,uid = np.unique(points,axis=0,return_index=True)
points = points[uid]
normals = normals[uid]
#normals = numpy_support.vtk_to_numpy(normals)
#Check and clean duplicate points
#points,idx = np.unique(points,axis=0,return_index=True)
#normals = normals[idx]
# later duplicate points will be allowed to accomodate C1
# surfaces which will require splitting during VTK NORMAL
# calculation. This will also have to make the splitting
# and PU angle thresholds the same to allow for non-singluar
# matricies.
return points,normals,data
[docs]def load3d_pv(filename,subdivisions=0,remesh=True,max_points=10000,verbosity=0):
mesh = pv.read(filename)
if remesh:
hausd = 0.01
mesh = remesh_surface(mesh,hausd=hausd,verbosity=verbosity)
previous = mesh.points.shape[0]
while mesh.points.shape[0] > max_points and mesh.points.shape[0] <= previous:
hausd += 0.01
print('Target: {} | Current: {}'.format(max_points,mesh.points.shape[0]))
previous = mesh.points.shape[0]
mesh = remesh_surface(mesh,hausd=hausd,verbosity=verbosity)
print('End Point Number: {}'.format(mesh.points.shape[0]))
points = mesh.points
normals = mesh.point_normals
upt,uid = np.unique(points,axis=0,return_index=True)
points = points[uid]
normals = normals[uid]
mesh.save(os.getcwd()+os.sep+'temp.vtp')
reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName(os.getcwd()+os.sep+'temp.vtp')
reader.Update()
mesh = reader.GetOutput()
os.remove(os.getcwd()+os.sep+'temp.vtp')
return points,normals,mesh