[vtkusers] Solidify-Modifier for VTK
Andras Lasso
lasso at queensu.ca
Thu May 3 22:22:50 EDT 2018
Yes, if you extrude in surface normal direction then there is a high chance that you will have self-intersecting faces. If you need a solution that guarantees accurate thickness and never generates self-intersecting faces, then you can compute a distance map using vtkImplicitModeller and create a surface from it using vtkContourFilter. Of course, computation time and memory need may be magnitudes higher than simple linear extrusion if you need highly accurate output.
By the way, it seems that your code does something very similar to vtkLinearExtrusionFilter. You might be able to simply use vtkLinearExtrusionFilter as is, or with an optional pre-shrinking step using vtkWarpVector (if you want to center the shell around the original surface).
Andras
-----Original Message-----
From: vtkusers <vtkusers-bounces at vtk.org> On Behalf Of sebastian_a
Sent: Thursday, May 3, 2018 1:08 PM
To: vtkusers at vtk.org
Subject: [vtkusers] Solidify-Modifier for VTK
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: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvtk.1045678.n5.nabble.com%2FVTK-Users-f1224199.html&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=vRH7ArAVsdhBuCbV4y0q5Mrwjpy67kt4lP31CcyAt3I%3D&reserved=0
_______________________________________________
Powered by https://na01.safelinks.protection.outlook.com/?url=www.kitware.com&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=uIJtEXHJ8hM6aVa2LvtwxcLH72mpiIY8o7EIj7sPKUQ%3D&reserved=0
Visit other Kitware open-source projects at https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.kitware.com%2Fopensource%2Fopensource.html&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=81ZsUqp2OK267v2r0Fi4ojqZSclsuUCC4Ncx5YIi2SA%3D&reserved=0
Please keep messages on-topic and check the VTK FAQ at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.vtk.org%2FWiki%2FVTK_FAQ&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=8Lw8%2BW41hXqOpKz2nFdotPXd12n%2BOnjMs4vqH2UulhE%3D&reserved=0
Search the list archives at: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmarkmail.org%2Fsearch%2F%3Fq%3Dvtkusers&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=uGL6MPhkkxNkm%2BIhENhvUihWTzlwlSoGKWLweUe1Jtg%3D&reserved=0
Follow this link to subscribe/unsubscribe:
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fvtk.org%2Fmailman%2Flistinfo%2Fvtkusers&data=02%7C01%7Classo%40queensu.ca%7C7ade740d2ac14ede567708d5b11873d7%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636609640949708331&sdata=MZNBfIJS0tZbEVQvawfnAQbhMhrEApMmfgnxWDbOIzY%3D&reserved=0
More information about the vtkusers
mailing list