Reputation: 11
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.
Upvotes: 1
Views: 1288
Reputation: 1337
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)
Upvotes: 1