def subdivide(actor, N=1, method=0, legend=None): ''' Increase the number of points in actor surface N = number of subdivisions method = 0, Loop method = 1, Linear method = 2, Adaptive method = 3, Butterfly ''' triangles = vtk.vtkTriangleFilter() setInput(triangles, polydata(actor)) triangles.Update() originalMesh = triangles.GetOutput() if method == 0: sdf = vtk.vtkLoopSubdivisionFilter() elif method == 1: sdf = vtk.vtkLinearSubdivisionFilter() elif method == 2: sdf = vtk.vtkAdaptiveSubdivisionFilter() elif method == 3: sdf = vtk.vtkButterflySubdivisionFilter() else: colors.printc('Error in subdivide: unknown method.', 'r') exit(1) if method != 2: sdf.SetNumberOfSubdivisions(N) setInput(sdf, originalMesh) sdf.Update() out = sdf.GetOutput() if legend is None and hasattr(actor, 'legend'): legend = actor.legend sactor = makeActor(out, legend=legend) sactor.GetProperty().SetOpacity(actor.GetProperty().GetOpacity()) sactor.GetProperty().SetColor(actor.GetProperty().GetColor()) sactor.GetProperty().SetRepresentation( actor.GetProperty().GetRepresentation()) return sactor
def subdivide_adapt(mesh, max_edge_length, max_triangle_area, max_num_triangles): triangles = vtk.vtkTriangleFilter() triangles.SetInputData(mesh._polydata) triangles.Update() originalMesh = triangles.GetOutput() sdf = vtk.vtkAdaptiveSubdivisionFilter() sdf.SetMaximumEdgeLength(max_edge_length) sdf.SetMaximumTriangleArea(max_triangle_area) sdf.SetMaximumNumberOfTriangles(max_num_triangles) sdf.SetInputData(originalMesh) sdf.Update() return mesh._update(sdf.GetOutput())
#!/usr/bin/env python import vtk from vtk.test import Testing from vtk.util.misc import vtkGetDataRoot VTK_DATA_ROOT = vtkGetDataRoot() # Create a pipeline: some skinny-ass triangles sphere = vtk.vtkSphereSource() sphere.SetThetaResolution(6) sphere.SetPhiResolution(24) ids = vtk.vtkIdFilter() ids.SetInputConnection(sphere.GetOutputPort()) adapt = vtk.vtkAdaptiveSubdivisionFilter() adapt.SetInputConnection(ids.GetOutputPort()) adapt.SetMaximumEdgeLength(0.1) #adapt.SetMaximumTriangleArea(0.01) #adapt.SetMaximumNumberOfPasses(1) adapt.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(adapt.GetOutputPort()) mapper.SetScalarModeToUseCellFieldData() mapper.SelectColorArray("vtkIdFilter_Ids") mapper.SetScalarRange(adapt.GetOutput().GetCellData().GetScalars().GetRange()) edgeProp = vtk.vtkProperty() edgeProp.EdgeVisibilityOn() edgeProp.SetEdgeColor(0, 0, 0)
def generate_cylinder_surface(r=10.0, h=20.0, res=100, subdivisions=0, max_edge=0, max_area=0, decimate=0, verbose=False): """ Generates a cylinder surface with minimal number of triangular cells and two circular planes. Args: r (float, optional): cylinder radius (default 10.0) h (float, optional): cylinder high (default 20.0) res (int, optional): resolution (default 100) subdivisions (int, optional): if > 0 (default 0) vtkLinearSubdivi- sionFilter is applied with this number of subdivisions max_edge (float, optional): if > 0 (default 0) vtkAdaptiveSubdivi- sionFilter is applied with this maximal triangle edge length max_area (float, optional): if > 0 (default 0) vtkAdaptiveSubdivi- sionFilter is applied with this maximal triangle area decimate (float, optional): if > 0 (default) vtkDecimatePro is applied with this target reduction (< 1) verbose (boolean, optional): if True (default False), some extra information will be printed out Returns: a cylinder surface (vtk.vtkPolyData) """ print("Generating a cylinder with radius={}, height={} and " "resolution={}".format(r, h, res)) is_positive_number(r) is_positive_number(h) is_positive_number(res) cylinder = vtk.vtkCylinderSource() # the origin around which the cylinder should be centered cylinder.SetCenter(0, 0, 0) # the radius of the cylinder cylinder.SetRadius(r) # the high of the cylinder cylinder.SetHeight(h) # polygonal discretization cylinder.SetResolution(res) # The cylinder is made of strips, so pass it through a triangle filter # to get a triangle mesh tri = vtk.vtkTriangleFilter() tri.SetInputConnection(cylinder.GetOutputPort()) # The cylinder has nasty discontinuities from the way the edges are # generated, so pass it though a CleanPolyDataFilter to merge any # points which are coincident or very close cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(tri.GetOutputPort()) cleaner.SetTolerance(0.005) cleaner.Update() # Reverse normals cylinder_surface = reverse_sense_and_normals(cleaner.GetOutputPort()) # Might contain non-triangle cells after cleaning - remove them cylinder_surface = remove_non_triangle_cells(cylinder_surface) if verbose: print("{} points".format(cylinder_surface.GetNumberOfPoints())) print("{} triangles".format(cylinder_surface.GetNumberOfCells())) if subdivisions > 0: cylinder_linear = vtk.vtkLinearSubdivisionFilter() cylinder_linear.SetNumberOfSubdivisions(subdivisions) cylinder_linear.SetInputData(cylinder_surface) cylinder_linear.Update() cylinder_surface = cylinder_linear.GetOutput() if verbose: print("{} points after linear subdivision".format( cylinder_surface.GetNumberOfPoints())) print("{} triangles after linear subdivision".format( cylinder_surface.GetNumberOfCells())) if max_area > 0 or max_edge > 0: cylinder_adaptive = vtk.vtkAdaptiveSubdivisionFilter() cylinder_adaptive.SetMaximumEdgeLength(max_edge) cylinder_adaptive.SetMaximumTriangleArea(max_area) cylinder_adaptive.SetInputData(cylinder_surface) cylinder_adaptive.Update() cylinder_surface = cylinder_adaptive.GetOutput() if verbose: print("{} points after adaptive subdivision".format( cylinder_surface.GetNumberOfPoints())) print("{} triangles after adaptive subdivision".format( cylinder_surface.GetNumberOfCells())) if decimate > 0: cylinder_decimate = vtk.vtkDecimatePro() cylinder_decimate.SetInputData(cylinder_surface) cylinder_decimate.SetTargetReduction(decimate) cylinder_decimate.PreserveTopologyOn() cylinder_decimate.SplittingOn() cylinder_decimate.BoundaryVertexDeletionOn() cylinder_decimate.Update() cylinder_surface = cylinder_decimate.GetOutput() if verbose: print("{} points after decimation".format( cylinder_surface.GetNumberOfPoints())) print("{} triangles after decimation".format( cylinder_surface.GetNumberOfCells())) return cylinder_surface
#!/usr/bin/env python import vtk from vtk.test import Testing from vtk.util.misc import vtkGetDataRoot VTK_DATA_ROOT = vtkGetDataRoot() # Create a pipeline: some skinny-ass triangles sphere = vtk.vtkSphereSource() sphere.SetThetaResolution(6) sphere.SetPhiResolution(24) ids = vtk.vtkIdFilter() ids.SetInputConnection(sphere.GetOutputPort()) adapt = vtk.vtkAdaptiveSubdivisionFilter() adapt.SetInputConnection(ids.GetOutputPort()) adapt.SetMaximumEdgeLength(0.1) #adapt.SetMaximumTriangleArea(0.01) #adapt.SetMaximumNumberOfPasses(1) adapt.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(adapt.GetOutputPort()) mapper.SetScalarModeToUseCellFieldData() mapper.SelectColorArray("vtkIdFilter_Ids") mapper.SetScalarRange(adapt.GetOutput().GetCellData().GetScalars().GetRange()) edgeProp = vtk.vtkProperty() edgeProp.EdgeVisibilityOn() edgeProp.SetEdgeColor(0,0,0)