如何在 Python 中计算平面(vtkCutter 对象)和 3D 几何图形之间的相交面积?

发布于 2025-01-09 17:39:14 字数 1791 浏览 5 评论 0原文

我一直(不成功)尝试使用 Python (v3.8.8) 中的 vtk 工具包来提取(切割)平面和给定 3D 形状之间的相交区域( STL 文件)。我开始定义 vtkCutter,执行剪切(使用平面)并使用 vtkStripper 和 vtkPolydata 提取多段线和交点(周长)(请参见下面的快照)。

def findIntersection(mySTL,Pt1,Pt2,midPt):
    # create cut plane
    lineVec = unitVec(Pt1,Pt2)
    plane = vtk.vtkPlane()
    plane.SetOrigin(midPt[0][0], midPt[0][1], midPt[0][2])
    plane.SetNormal(lineVec[0],lineVec[1],lineVec[2])
    # create cutter
    cutEdges = vtk.vtkCutter()
    cutEdges.SetInputConnection(mySTL)
    cutEdges.SetCutFunction(plane)
    cutEdges.GenerateCutScalarsOn()
    cutEdges.SetValue(0, 0.5)
    cutStrips = vtk.vtkStripper()
    cutStrips.SetInputConnection(cutEdges.GetOutputPort())
    cutStrips.Update()
    # get polydata intersection (plane vs stl)
    cutPoly = vtk.vtkPolyData()
    cutPoly.SetPoints(cutStrips.GetOutput().GetPoints())
    cutPoly.SetPolys(cutStrips.GetOutput().GetLines())

    return cutEdges, cutPoly, cutStrips

我尝试了各种方法来提取交叉区域(除了下面报告的一种方法都失败了,它返回了预期范围内的值)。然而,我得到的值与我信任的其他软件中执行的独立测量相差甚远。

def getIntersectArea(contour):
    CoM = vtk.vtkCenterOfMass()
    CoM.SetInputData(contour) #contour is the vtk.PolyData (e.g cutPoly)
    CoM.SetUseScalarsAsWeights(False)
    CoM.Update()
    Center = CoM.GetCenter()
    area = float(0)
    points = contour.GetCell(0).GetPoints()
    numberOfPoints = points.GetNumberOfPoints()
    for i in range(numberOfPoints):
        point0 = points.GetPoint(i)
        point1 = points.GetPoint((i+1)%numberOfPoints)
        pArea = vtk.vtkTriangle.TriangleArea(Center,point0,point1)
        area = area+float(pArea)

    return area

到目前为止,我还没有找到合适的解决方案。有谁有解决方案或可以向我指出其他讨论(我可能错过了)?

谢谢!

PS:我正在利用 vtk 库对 STL 文件执行一系列其他操作,一切正常。

I have been (unsuccessfully) trying to use the vtk toolkit in Python (v3.8.8) to extract the intersection area between a (cutting) plane and a given 3D shape (STL file). I get to the point of defining a vtkCutter, perform the clipping (with a plane) and extract the polyline and points (perimeter) of the intersection using a vtkStripper and vtkPolydata (see snapshot below).

def findIntersection(mySTL,Pt1,Pt2,midPt):
    # create cut plane
    lineVec = unitVec(Pt1,Pt2)
    plane = vtk.vtkPlane()
    plane.SetOrigin(midPt[0][0], midPt[0][1], midPt[0][2])
    plane.SetNormal(lineVec[0],lineVec[1],lineVec[2])
    # create cutter
    cutEdges = vtk.vtkCutter()
    cutEdges.SetInputConnection(mySTL)
    cutEdges.SetCutFunction(plane)
    cutEdges.GenerateCutScalarsOn()
    cutEdges.SetValue(0, 0.5)
    cutStrips = vtk.vtkStripper()
    cutStrips.SetInputConnection(cutEdges.GetOutputPort())
    cutStrips.Update()
    # get polydata intersection (plane vs stl)
    cutPoly = vtk.vtkPolyData()
    cutPoly.SetPoints(cutStrips.GetOutput().GetPoints())
    cutPoly.SetPolys(cutStrips.GetOutput().GetLines())

    return cutEdges, cutPoly, cutStrips

I tried various methods to extract the intersection area (all failing but one – reported below - that returns values in the expected ranges). However, I am getting values far from independent measures performed in other software, which I trust.

def getIntersectArea(contour):
    CoM = vtk.vtkCenterOfMass()
    CoM.SetInputData(contour) #contour is the vtk.PolyData (e.g cutPoly)
    CoM.SetUseScalarsAsWeights(False)
    CoM.Update()
    Center = CoM.GetCenter()
    area = float(0)
    points = contour.GetCell(0).GetPoints()
    numberOfPoints = points.GetNumberOfPoints()
    for i in range(numberOfPoints):
        point0 = points.GetPoint(i)
        point1 = points.GetPoint((i+1)%numberOfPoints)
        pArea = vtk.vtkTriangle.TriangleArea(Center,point0,point1)
        area = area+float(pArea)

    return area

I have not been able to find an appropriate solution, as of yet. Does anyone have a solution or can point me to other discussions (which I may have missed)?

Thanks!

PS: I am exploiting the vtk library to perform a bunch of other operations on STL files, all working.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌能量女王 2025-01-16 17:39:14

使用 vedo

from vedo import *

msh = Mesh(dataurl+'bunny.obj').scale(3).shift(0,-0.5,0.01)
plane = Grid(resx=100, resy=100).wireframe(False)

cutplane = plane.clone().cutWithMesh(msh).triangulate()
area = cutplane.area()

show([[msh, plane], [cutplane, f"area: {area}"]], N=2, axes=1)

在此处输入图像描述

Using vedo:

from vedo import *

msh = Mesh(dataurl+'bunny.obj').scale(3).shift(0,-0.5,0.01)
plane = Grid(resx=100, resy=100).wireframe(False)

cutplane = plane.clone().cutWithMesh(msh).triangulate()
area = cutplane.area()

show([[msh, plane], [cutplane, f"area: {area}"]], N=2, axes=1)

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文