У меня есть STL гироида, и я хочу обрезать его сферой (предыдущий вопрос)
Теперь у меня есть данные, представленные правильным образом, но всякий раз, когда я выполняю логическую операцию над своими двумя объектами, я получаю пустой результат.
import vtk
colors = vtk.vtkNamedColors()
file_name = 'gyroid.stl'
# Load poly from STL
reader = vtk.vtkSTLReader()
reader.SetFileName(file_name)
reader.Update()
polyData = reader.GetOutput()
# Centre of poly
x = (polyData.GetBounds()[1] - polyData.GetBounds()[0]) / 2.0
y = (polyData.GetBounds()[3] - polyData.GetBounds()[2]) / 2.0
z = (polyData.GetBounds()[5] - polyData.GetBounds()[4]) / 2.0
# Set up cropping sphere
sphereSource = vtk.vtkSphereSource()
sphereSource.SetCenter(x, y, z)
sphereSource.SetPhiResolution(41)
sphereSource.SetThetaResolution(41)
sphereSource.SetRadius(63)
sphereSource.Update()
sphere = sphereSource.GetOutput()
# Boolean operations on poly with sphere
booleanOperation = vtk.vtkBooleanOperationPolyDataFilter()
booleanOperation.SetOperationToIntersection()
# booleanOperation.SetOperationToDifference()
# booleanOperation.SetOperationToUnion()
booleanOperation.SetInputData(0, polyData)
booleanOperation.SetInputData(1, sphere)
# # Output result to STL
# stlWriter = vtk.vtkSTLWriter()
# stlWriter.SetFileName("sphere_cropped.stl")
# stlWriter.SetInputConnection(booleanOperation.GetOutputPort())
# stlWriter.Write()
# Set up poly for display
polyDataMapper = vtk.vtkPolyDataMapper()
polyDataMapper.SetInputData(polyData)
polyDataMapper.ScalarVisibilityOff()
polyDataActor = vtk.vtkActor()
polyDataActor.SetMapper(polyDataMapper)
polyDataActor.GetProperty().SetDiffuseColor(colors.GetColor3d('Tomato'))
polyDataActor.GetProperty().SetSpecular(0.6)
polyDataActor.GetProperty().SetSpecularPower(20)
polyDataActor.SetPosition(polyData.GetBounds()[1] - polyData.GetBounds()[0], 0, 0)
# Set up sphere for display
sphereMapper = vtk.vtkPolyDataMapper()
sphereMapper.SetInputData(sphere)
sphereMapper.ScalarVisibilityOff()
sphereActor = vtk.vtkActor()
sphereActor.SetMapper(sphereMapper)
sphereActor.GetProperty().SetDiffuseColor(colors.GetColor3d('Mint'))
sphereActor.GetProperty().SetSpecular(0.6)
sphereActor.GetProperty().SetSpecularPower(20)
sphereActor.SetPosition(-(polyData.GetBounds()[1] - polyData.GetBounds()[0]), 0, 0)
# Set up Boolean result for display
booleanOperationMapper = vtk.vtkPolyDataMapper()
booleanOperationMapper.SetInputConnection(booleanOperation.GetOutputPort())
booleanOperationMapper.ScalarVisibilityOff()
booleanOperationActor = vtk.vtkActor()
booleanOperationActor.SetMapper(booleanOperationMapper)
booleanOperationActor.GetProperty().SetDiffuseColor(colors.GetColor3d('Banana'))
booleanOperationActor.GetProperty().SetSpecular(0.6)
booleanOperationActor.GetProperty().SetSpecularPower(20)
# Display all
renderer = vtk.vtkRenderer()
renderer.AddViewProp(polyDataActor)
renderer.AddViewProp(sphereActor)
renderer.AddViewProp(booleanOperationActor)
renderer.SetBackground(colors.GetColor3d('Silver'))
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.SetSize(640, 480)
renderWindow.SetWindowName('BooleanOperationPolyDataFilter')
renWinInteractor = vtk.vtkRenderWindowInteractor()
renWinInteractor.SetRenderWindow(renderWindow)
renderWindow.Render()
renWinInteractor.Start()
Я понимаю, что гироиды представляют собой сложные поверхности, и мне было интересно, не в этом ли проблема? Нужно ли мне дополнительно обрабатывать полигональные данные, прежде чем я получу разумные ответы, или это просто тот случай, когда логические операторы VTK не работают?
Код для генерации gyroid.stl
import numpy as np
from numpy import sin, cos, pi
from skimage import measure
import stl
from stl import mesh
def gyroid(x, y, z, t):
return cos(x)*sin(y) + cos(y)*sin(z) + cos(z)*sin(x) + t
lattice_param = 1.5
strut_param = 0
resolution = 127j
x, y, z = pi*np.mgrid[-1:1:resolution, -1:1:resolution, -1:1:resolution] * lattice_param
vol = gyroid(x, y, z, strut_param)
verts, faces, normals, values = measure.marching_cubes_lewiner(vol, 0, spacing=(0.1, 0.1, 0.1))
data = np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)
gyr_mesh = mesh.Mesh(data, remove_empty_areas=False)
for i, f in enumerate(faces):
for j in range(3):
gyr_mesh.vectors[i][j] = verts[f[j],:] * 10.0
gyr_mesh.save('gyroid.stl')