首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >产生空集的poly数据上的VTK布尔操作

产生空集的poly数据上的VTK布尔操作
EN

Stack Overflow用户
提问于 2020-12-04 00:21:36
回答 1查看 107关注 0票数 0

我有一个陀螺仪的STL &我想用一个球体裁剪它(previous question)

现在我已经以正确的方式表示了数据,但是每当我对我的2个对象执行布尔操作时,我都会得到一个空的结果。

代码语言:javascript
运行
复制
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的代码

代码语言:javascript
运行
复制
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')
EN

回答 1

Stack Overflow用户

发布于 2020-12-05 04:03:57

我发布了一个可能的解决方案here。使用布尔过滤器的变体会给出合理的结果:

代码语言:javascript
运行
复制
from vedo import *
import numpy as np

x, y, z = np.mgrid[:30,:30,:30] * 0.4
U = sin(x)*cos(y) + sin(y)*cos(z) + sin(z)*cos(x)

# Create a Volume, take the isosurface at 0 and smooth it
g = Volume(U).isosurface(0).smoothLaplacian()

# Intersect with a sphere
s = Sphere(pos=(15,15,15), r=14, quads=True).triangulate()
gxs = g.boolean('intersect',s).clean().computeNormals()
gxs.color('silver').lighting('metallic')

show([[g,s],gxs], N=2, bg='wheat', bg2='lightblue', axes=5)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65129906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档