current position:Home>Mapping 3D model surface distances using Python VTK

Mapping 3D model surface distances using Python VTK

2022-01-31 05:55:25 Pie star's keyboard

This is my participation 11 The fourth of the yuegengwen challenge 7 God , Check out the activity details :2021 One last more challenge

This article explains how to use it VTK Read the picture and calculate two three-dimensional models (stl) Surface distance of , And map its distance value to the model .

Data preparation : Need to prepare two stl file 、Python Need to install vtk library

Step one : data fetch First, through vtk.vtkSTLReader() Definition stl File reading interface , Re pass reader1.GetOutput() You can get stl stay vtk Workflow data .

Step two : Remove duplicate points adopt vtk.vtkCleanPolyData() You can remove duplicate points in the model

Step three : Calculated distance Use vtk.vtkDistancePolyDataFilter() , Use the data after filtering out duplicate points in the previous step as input . Such as distanceFilter.SetInputConnection(1, clean1.GetOutputPort()), The first parameter is the label of the input data , from 0 Start counting ; The second parameter is the input data . We will vtkDistancePolyDataFilter Of output to mapper The distance mapping is completed .

Step four : Color configuration lut = vtk.vtkLookupTable() Equivalent to a palette function , By changing its parameters , Adjust the color range of the final mapping . scalarBar = vtk.vtkScalarBarActor() It's the color bar , Map the distance value to color according to the results of the previous palette .

import vtk

input1 = vtk.vtkPolyData()
reader1 = vtk.vtkSTLReader()
reader1.SetFileName('model1.stl')
reader1.Update()
input1 = reader1.GetOutput()  #  Read the model A

input2 = vtk.vtkPolyData()
reader2 = vtk.vtkSTLReader()
reader2.SetFileName('model2.stl')
reader2.Update()
input2 = reader2.GetOutput()  #  Read the model B


#  Data merging , You can merge and display two models 
clean1 = vtk.vtkCleanPolyData()
clean1.SetInputData(input1)

clean2 = vtk.vtkCleanPolyData()
clean2.SetInputData(input2)

distanceFilter = vtk.vtkDistancePolyDataFilter()

distanceFilter.SetInputConnection(1, clean1.GetOutputPort())
distanceFilter.SetInputConnection(0, clean2.GetOutputPort())
distanceFilter.SignedDistanceOff()
distanceFilter.Update()  #  Calculated distance 
distanceFilter.GetOutputPort()
mapper = vtk.vtkPolyDataMapper()  #  To configure mapper
mapper.SetInputConnection(distanceFilter.GetOutputPort())
mapper.SetScalarRange(  #  Set the color mapping range 
    distanceFilter.GetOutput().GetPointData().GetScalars().GetRange()[0],
    distanceFilter.GetOutput().GetPointData().GetScalars().GetRange()[1])
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor1 = vtk.vtkActor()
actor1.SetMapper(mapper)
lut = vtk.vtkLookupTable()
lut.SetHueRange(0.2, 0.7)  #  Mapped color transformation parameters ( Adjust your own color )
# lut.SetAlphaRange(1.0, 1.0)
# lut.SetValueRange(1.0, 1.0)
# lut.SetSaturationRange(1.0, 1.0)
# lut.SetNumberOfTableValues(256)
mapper.SetLookupTable(lut)
mapper2 = vtk.vtkPolyDataMapper()
mapper2.SetInputData((distanceFilter.GetSecondDistanceOutput()))
mapper2.SetScalarRange(  #  Set the color mapping range 
    distanceFilter.GetSecondDistanceOutput().GetPointData().GetScalars().GetRange()[0],
    distanceFilter.GetSecondDistanceOutput().GetPointData().GetScalars().GetRange()[1])


actor2 = vtk.vtkActor()
actor2.SetMapper(mapper2)

scalarBar = vtk.vtkScalarBarActor()  #  Set up color_bar
scalarBar.SetLookupTable(mapper.GetLookupTable())
scalarBar.SetTitle("SD(mm)")
scalarBar.SetNumberOfLabels(5)  #  Set the number of scale labels to display . Set the position of the ribbon by yourself 
scalarBar.SetMaximumNumberOfColors(10)
# scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
# scalarBar.GetPositionCoordinate().SetValue(0.01, 0.49) #  The smaller the parameter, the more left , The larger the second parameter is, the higher it goes 
# scalarBar.SetWidth(0.16)
# scalarBar.SetHeight(0.5)
# scalarBar.SetTextPositionToPrecedeScalarBar() #  Whether the title and scale mark should precede the scalar column ( The text will appear to the left of the bar )
# #  Set the margin between the title and the bar 
# scalarBar.SetVerticalTitleSeparation(10)
# #  Set the title color 
scalarBar.DrawTickLabelsOn()
scalarBar.GetTitleTextProperty().SetColor(0, 0, 0)
scalarBar.GetLabelTextProperty().SetColor(0, 0, 0)
arender = vtk.vtkRenderer()
arender.SetViewport(0, 0.0, 1, 1.0)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(arender)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
style = vtk.vtkInteractorStyleTrackballActor()
iren.SetInteractorStyle(style)
aCamera = vtk.vtkCamera()
aCamera.SetViewUp(0, 0, -1)
aCamera.SetPosition(0, -1, 0)
aCamera.ComputeViewPlaneNormal()
aCamera.Azimuth(30.0)
aCamera.Elevation(30.0)
aCamera.Dolly(1.5)

arender.AddActor(actor)
# arender.AddActor(actor1)
arender.SetActiveCamera(aCamera)
arender.ResetCamera()
arender.SetBackground(1, 1, 1)
arender.ResetCameraClippingRange()
arender.AddActor2D(scalarBar)

renWin.Render()
iren.Initialize()
iren.Start()
 Copy code 

Result example :

1636355834(1).jpg

copyright notice
author[Pie star's keyboard],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/01/202201310555231274.html

Random recommended