def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkWeightedTransformFilter(), 'Processing.', ('vtkPointSet',), ('vtkPointSet',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def DeformSurface(self): # interpolate and sample the displacement norms over the surface rbf = vtkvmtkcontrib.vtkvmtkRBFInterpolation2() rbf.SetSource(self.SourceSpheres) rbf.SetRBFTypeToBiharmonic() rbf.ComputeCoefficients() sampler = vtkvmtkcontrib.vtkvmtkPolyDataSampleFunction() sampler.SetInput(self.Surface) sampler.SetImplicitFunction(rbf) sampler.SetSampleArrayName("DisplacementNorms") sampler.Update() sampArray = sampler.GetOutput().GetPointData().GetArray("DisplacementNorms") ##Clamp the negative values to 0 and the positive values to one in a weight array calculator = vtk.vtkArrayCalculator() calculator.SetInput(sampler.GetOutput()) calculator.AddScalarArrayName("DisplacementNorms") calculator.SetFunction("if( DisplacementNorms > 0 , iHat, jHat)") calculator.SetResultArrayName("Weights") calculator.SetResultArrayType(vtk.VTK_FLOAT) calculator.Update() # Create the transform thinPlateSplineTransform = vtk.vtkThinPlateSplineTransform() thinPlateSplineTransform.SetBasisToR() thinPlateSplineTransform.SetSourceLandmarks(self.SourcePoints) thinPlateSplineTransform.SetTargetLandmarks(self.TargetPoints) transform = vtk.vtkTransform() transform.Identity() transform2 = vtk.vtkTransform() transform2.Identity() # Apply weighted transform transformFilter = vtk.vtkWeightedTransformFilter() transformFilter.SetInput(calculator.GetOutput()) transformFilter.SetNumberOfTransforms(3) transformFilter.SetWeightArray("Weights") transformFilter.SetTransform(thinPlateSplineTransform, 0) transformFilter.SetTransform(transform, 1) transformFilter.SetTransform(transform2, 2) transformFilter.Update() normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInput(transformFilter.GetOutput()) normalsFilter.Update() # FIXME: the normal filter apparently introduced some holes in some meshes (wtf?). This filter cleans the mesh cleanFilter = vtk.vtkCleanPolyData() cleanFilter.SetInput(normalsFilter.GetOutput()) cleanFilter.Update() self.DeformedSurface = cleanFilter.GetOutput()
tfarray.SetComponent(i, 0, zn1) tfarray.SetComponent(i, 1, zn) i = i + 1 # create field data to hold the array, and bind it to the sphere fd = vtk.vtkFieldData() tfarray.SetName("weights") sphereData.GetPointData().AddArray(tfarray) # use an ordinary transform to stretch the shape stretch = vtk.vtkTransform() stretch.Scale(1, 1, 3.2) stretchFilter = vtk.vtkTransformFilter() stretchFilter.SetInputData(sphereData) stretchFilter.SetTransform(stretch) # now, for the weighted transform stuff weightedTrans = vtk.vtkWeightedTransformFilter() # create two transforms to interpolate between identity = vtk.vtkTransform() identity.Identity() rotated = vtk.vtkTransform() rotatedAngle = 45 rotated.RotateX(rotatedAngle) weightedTrans.SetNumberOfTransforms(2) weightedTrans.SetTransform(identity, 0) weightedTrans.SetTransform(rotated, 1) # which data array should the filter use ? weightedTrans.SetWeightArray("weights") weightedTrans.SetInputConnection(stretchFilter.GetOutputPort()) weightedTransMapper = vtk.vtkPolyDataMapper() weightedTransMapper.SetInputConnection(weightedTrans.GetOutputPort()) weightedTransActor = vtk.vtkActor()
# create field data to hold the array, and bind it to the sphere fd = vtk.vtkFieldData() tfarray.SetName("weights") sphereData.GetPointData().AddArray(tfarray) # use an ordinary transform to stretch the shape stretch = vtk.vtkTransform() stretch.Scale(1, 1, 3.2) stretchFilter = vtk.vtkTransformFilter() stretchFilter.SetInputData(sphereData) stretchFilter.SetTransform(stretch) # now, for the weighted transform stuff weightedTrans = vtk.vtkWeightedTransformFilter() # create two transforms to interpolate between identity = vtk.vtkTransform() identity.Identity() rotated = vtk.vtkTransform() rotatedAngle = 45 rotated.RotateX(rotatedAngle) weightedTrans.SetNumberOfTransforms(2) weightedTrans.SetTransform(identity, 0) weightedTrans.SetTransform(rotated, 1) # which data array should the filter use ? weightedTrans.SetWeightArray("weights")
def __init__(self): super().__init__() verts = np.loadtxt('tentacle_verts.txt') faces = np.loadtxt('tentacle_polys.txt') bone_dat = np.loadtxt('tentacle_weights.txt') bones = np.unique(bone_dat[:, 0]) bones = np.unique(bone_dat[:, 0]) # We'll create the building blocks of polydata including data attributes. polyData = vtk.vtkPolyData() points = vtk.vtkPoints() polys = vtk.vtkCellArray() scalars = vtk.vtkFloatArray() weights = np.zeros((len(verts), len(bones))) # Load the point, cell, and data attributes. for v in verts: points.InsertPoint(int(v[0]), v[1:]) for pt in faces: polys.InsertNextCell(mkVtkIdList(pt[1:].astype(int))) for bone in bones: idx = np.round( bone_dat[np.where(bone_dat[:, 0] == bone)][:, 1]).astype(int) weights[idx, int(bone)] = bone_dat[np.where(bone_dat[:, 0] == bone)][:, 2] polyData.SetPoints(points) polyData.SetPolys(polys) normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polyData) normalGenerator.ComputePointNormalsOn() normalGenerator.ComputeCellNormalsOn() normalGenerator.Update() tfarray = vtk.vtkFloatArray() npoints = polyData.GetNumberOfPoints() bounds = polyData.GetBounds() tfarray.SetNumberOfComponents(len(bones)) tfarray.SetNumberOfTuples(npoints) for i, weight in enumerate(weights): for j in range(len(bones)): tfarray.SetComponent(i, j, weight[j]) tfarray.SetName("weights") polyData.GetPointData().AddArray(tfarray) # Now, for the weighted transform stuff weightedTrans = vtk.vtkWeightedTransformFilter() weightedTrans.SetNumberOfTransforms(len(bones)) self.transforms = [vtk.vtkTransform() for bone in bones] for i in range(len(self.transforms)): self.transforms[i].Identity() # self.transforms[i].RotateX(i*10) # self.transforms[i].Translate(0,0,1*i) weightedTrans.SetTransform(self.transforms[i], i) # Which data array should the filter use ? weightedTrans.SetWeightArray("weights") weightedTrans.SetInputConnection(normalGenerator.GetOutputPort()) smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputConnection(weightedTrans.GetOutputPort()) smoothFilter.SetNumberOfIterations(15) smoothFilter.SetRelaxationFactor(0.2) # smoothFilter.FeatureEdgeSmoothingOn() # smoothFilter.BoundarySmoothingOn() weightedTransMapper = vtk.vtkPolyDataMapper() weightedTransMapper.SetInputConnection(smoothFilter.GetOutputPort()) with open("perlin.glsl", "r") as file: shader_str = file.read() weightedTransMapper.SetVertexShaderCode( "//VTK::System::Dec\n" # always start with this line "attribute vec4 vertexMC;\n" + shader_str + # use the default normal decl as the mapper # will then provide the normalMatrix uniform # which we use later on "//VTK::Normal::Dec\n" "varying vec4 myVertexMC;\n" "varying vec3 myNormalMCVSOutput;\n" "uniform mat4 MCDCMatrix;\n" "void main () {\n" " normalVCVSOutput = normalMatrix * normalMC;\n" # do something weird with the vertex positions # this will mess up your head if you keep # rotating and looking at it, very trippy # " vec4 tmpPos = MCDCMatrix * vertexMC;\n" " float disp = 0.00;\n" " vec4 tmpPos = MCDCMatrix * vec4(vertexMC.x+normalMC.x*disp, vertexMC.y+normalMC.y*disp, vertexMC.z+normalMC.z*disp, 1.0);\n" # " gl_Position = tmpPos*vec4(0.2+0.8*abs(tmpPos.x),0.2+0.8*abs(tmpPos.y),1.0,1.0);\n" " gl_Position = tmpPos;\n" " myVertexMC = vertexMC;\n" "}\n") # weightedTransMapper.AddShaderReplacement( # vtk.vtkShader.Vertex, # "//VTK::Normal::Dec", # replace the normal block # True, # before the standard replacements # "//VTK::Normal::Dec\n" # we still want the default # " varying vec3 myNormalMCVSOutput;\n" #but we add this # " out vec4 myVertexMC;\n", # False # only do it once # ) weightedTransMapper.AddShaderReplacement( vtk.vtkShader.Vertex, "//VTK::Normal::Impl", # replace the normal block True, # before the standard replacements "//VTK::Normal::Impl\n" # we still want the default " myNormalMCVSOutput = normalMC;\n" #but we add this " myVertexMC = vertexMC;\n", False # only do it once ) # Add the code to generate noise # These functions need to be defined outside of main. Use the System::Dec # to declare and implement weightedTransMapper.AddShaderReplacement( vtk.vtkShader.Fragment, "//VTK::System::Dec", False, # after the standard replacements "//VTK::System::Dec\n" + shader_str, False # only do it once ) # now modify the fragment shader weightedTransMapper.AddShaderReplacement( vtk.vtkShader.Fragment, # in the fragment shader "//VTK::Normal::Dec", # replace the normal block True, # before the standard replacements "//VTK::Normal::Dec\n" # we still want the default " varying vec3 myNormalMCVSOutput;\n" #but we add this " varying vec4 myVertexMC;\n" " uniform float k = 1.0;\n", False # only do it once ) # # weightedTransMapper.AddShaderReplacement( # # vtk.vtkShader.Fragment, # in the fragment shader # # "//VTK::Normal::Impl", # replace the normal block # # True, # before the standard replacements # # "//VTK::Normal::Impl\n" # we still want the default calc # # " diffuseColor = abs(myNormalMCVSOutput);\n", #but we add this # # False # only do it once # # ) # weightedTransMapper.AddShaderReplacement( # vtk.vtkShader.Fragment, # in the fragment shader # "//VTK::Normal::Impl", # replace the normal block # True, # before the standard replacements # "//VTK::Normal::Impl\n" # we still want the default calc # " diffuseColor = abs(myNormalMCVSOutput);\n", #but we add this # False # only do it once # ) weightedTransMapper.AddShaderReplacement( vtk.vtkShader.Fragment, # in the fragment shader "//VTK::Light::Impl", # replace the light block False, # after the standard replacements "//VTK::Light::Impl\n" # we still want the default calc "#define pnoise(x) ((noise(x) + 1.0) / 2.0)\n" " vec3 noisyColor;\n" " noisyColor.r = noise(k * 100.0 * myVertexMC);\n" " noisyColor.g = noise(k * 11.0 * myVertexMC);\n" " noisyColor.b = noise(k * 12.0 * myVertexMC);\n" " fragOutput0.rgb = opacity * vec3(ambientColor + diffuse);\n" " fragOutput0.rgb = vec3(1, 1, 1) - fragOutput0.r * (noisyColor.b/10.0 + 0.9);" # " fragOutput0.rgb = opacity * vec3(ambientColor + diffuse + specular);\n" " fragOutput0.g = fragOutput0.g / 2.0 * (1.0 - noisyColor.r/5.0 + 0.8);" " fragOutput0.b = fragOutput0.r / 2.0 * (1.0 - noisyColor.r/5.0 + 0.8);" " fragOutput0.r = fragOutput0.b * (1.0 - noisyColor.r/5.0 + 0.8);" " fragOutput0.rgb = fragOutput0.rgb * 0.8 + abs(noisyColor.r) * specular * 2;" " fragOutput0.a = opacity;\n", False # only do it once ) self.SetMapper(weightedTransMapper) self.GetProperty().SetColor(1, 1, 0) self.GetProperty().SetAmbientColor(0.2, 0.2, 0.2) self.GetProperty().SetDiffuseColor(1.0, 1.0, 1.0) self.GetProperty().SetSpecularColor(1.0, 1.0, 1.0) self.GetProperty().SetSpecular(0.5) self.GetProperty().SetDiffuse(0.7) self.GetProperty().SetAmbient(0.1) self.GetProperty().SetSpecularPower(100.0) self.GetProperty().SetOpacity(1.0) self.GetProperty().BackfaceCullingOn()