[vtkusers] Solidify-Modifier for VTK
sebastian_a
seb.an at icloud.com
Thu May 3 13:08:07 EDT 2018
Hello,
I created a Blender-like Solidify-Algorithm. Maybe it helps someone.
Unfortunately, also like the one in Blender, it has the following problem:
If the Solidification-Thickness to large (for example larger than half the
distance to an opponent face), it creates inside-out-errors.
Do you have any suggestions how to fix this nicely?
Thanks, Sebastian
import vtk
import numpy as np
solidificationThickness = 2
# polydataSource = vtk.vtkSTLReader()
# polydataSource.SetFileName("testmodel.stl")
# polydataSource.Update()
polydataSource = vtk.vtkSphereSource()
polydataSource.SetRadius(10)
polydataSource.SetThetaResolution(5)
polydataSource.SetPhiResolution(3)
polydataSource.Update()
# remove double vertices
cleanPolyData = vtk.vtkCleanPolyData()
cleanPolyData.SetInputData(polydataSource.GetOutput())
cleanPolyData.Update()
# create normals
normals = vtk.vtkPolyDataNormals()
normals.SetComputeCellNormals(1)
normals.SetInputData(cleanPolyData.GetOutput())
normals.SplittingOff()
normals.Update()
polydata = vtk.vtkPolyData()
polydata.DeepCopy(normals.GetOutput())
numberOfPoints = polydata.GetNumberOfPoints()
print polydata.GetNumberOfPoints()
# get boundary edges, used later
featureEdges = vtk.vtkFeatureEdges()
featureEdges.BoundaryEdgesOn()
featureEdges.ColoringOff()
featureEdges.FeatureEdgesOff()
featureEdges.NonManifoldEdgesOff()
featureEdges.ManifoldEdgesOff()
featureEdges.SetInputData(normals.GetOutput())
featureEdges.Update()
# check for intersection
cellLocator = vtk.vtkOBBTree()
cellLocator.SetDataSet(polydata)
cellLocator.BuildLocator()
addingPoints = []
addingPolys = []
for pointID in range(numberOfPoints):
cellIDs = vtk.vtkIdList()
polydata.GetPointCells(pointID, cellIDs)
normalsArray = []
# ilterate through all cells/faces which contain point
for id in xrange(cellIDs.GetNumberOfIds()):
# faceData = []
n = []
n.append(polydata.GetCellData().GetArray('Normals').GetValue(cellIDs.GetId(id)*3))
n.append(polydata.GetCellData().GetArray('Normals').GetValue(cellIDs.GetId(id)*3
+ 1))
n.append(polydata.GetCellData().GetArray('Normals').GetValue(cellIDs.GetId(id)*3
+ 2))
normalsArray.append(np.array(n) * (-1))
# calculate position of new vert
dir_vec = np.zeros(3)
for n in normalsArray:
dir_vec = dir_vec + np.array(n)
dir_vec_norm = dir_vec / np.linalg.norm(dir_vec)
proj_length = np.dot(dir_vec_norm, np.array(normalsArray[0]))
dir_vec_finallenght = dir_vec_norm * proj_length
vertex_neu = np.array(polydata.GetPoint(pointID)) + (dir_vec_finallenght *
solidificationThickness)
addingPoints.append(vertex_neu)
for cellID in range(polydata.GetNumberOfCells()):
pointIDs = vtk.vtkIdList()
polydata.GetCellPoints(cellID, pointIDs)
newPointIDs = vtk.vtkIdList()
for i in reversed(range(pointIDs.GetNumberOfIds())):
newPointIDs.InsertNextId(int(pointIDs.GetId(i) + numberOfPoints))
addingPolys.append(newPointIDs)
doubleSurfacePoints = vtk.vtkPoints()
doubleSurfacePolys = vtk.vtkCellArray()
doubleSurfacePoints.DeepCopy(polydata.GetPoints())
doubleSurfacePolys.DeepCopy(polydata.GetPolys())
addedPoints = vtk.vtkPoints()
for p in addingPoints:
doubleSurfacePoints.InsertNextPoint(p)
addedPoints.InsertNextPoint(p)
for p in addingPolys:
doubleSurfacePolys.InsertNextCell(p)
doubleSurfacePD = vtk.vtkPolyData()
doubleSurfacePD.SetPoints(doubleSurfacePoints)
doubleSurfacePD.SetPolys(doubleSurfacePolys)
# add faces to boundary edges
mergePoints = vtk.vtkMergePoints()
mergePoints.InitPointInsertion(doubleSurfacePD.GetPoints(),
doubleSurfacePD.GetBounds())
mergePoints.SetDataSet(doubleSurfacePD)
mergePoints.BuildLocator()
watertightPolys = vtk.vtkCellArray()
watertightPolys.DeepCopy(doubleSurfacePD.GetPolys())
watertightPoints = vtk.vtkPoints()
watertightPoints.DeepCopy(doubleSurfacePD.GetPoints())
for e in range(featureEdges.GetOutput().GetNumberOfCells()):
pointIDs = vtk.vtkIdList()
featureEdges.GetOutput().GetCellPoints(e, pointIDs)
if pointIDs.GetNumberOfIds() == 2: # -> Edge
matchingPointIDs = []
newPointIDs = vtk.vtkIdList()
for p in range(2):
matchingPointIDs.append(mergePoints.IsInsertedPoint(featureEdges.GetOutput().GetPoint(pointIDs.GetId(p))))
if not (-1) in matchingPointIDs: # edge vertex not found in original pd,
should not happen
newPointIDs.InsertNextId(matchingPointIDs[1])
newPointIDs.InsertNextId(matchingPointIDs[0])
newPointIDs.InsertNextId(matchingPointIDs[0]+numberOfPoints)
newPointIDs.InsertNextId(matchingPointIDs[1]+numberOfPoints)
watertightPolys.InsertNextCell(newPointIDs)
watertightPD = vtk.vtkPolyData()
watertightPD.SetPoints(watertightPoints)
watertightPD.SetPolys(watertightPolys)
# triangulate new connecting faces
triangleFilter = vtk.vtkTriangleFilter()
triangleFilter.SetInputData(watertightPD)
triangleFilter.Update()
# visualize
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(triangleFilter.GetOutput())
actor = vtk.vtkActor()
actor.GetProperty().SetEdgeVisibility(1)
actor.GetProperty().SetOpacity(0.5)
actor.GetProperty().BackfaceCullingOn()
#actor.GetProperty().SetRepresentationToWireframe()
actor.SetMapper(mapper)
camera = vtk.vtkCamera()
camera.SetPosition(1,1,1)
camera.SetFocalPoint(0,0,0)
renderer = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
renderer.AddActor(actor)
renderer.SetActiveCamera(camera)
renderer.ResetCamera()
renderer.SetBackground(1,1,1)
renWin.SetSize(300,300)
renWin.Render()
iren.Start()
--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
More information about the vtkusers
mailing list