def disc(pos=[0, 0, 0], normal=[0, 0, 1], r1=0.5, r2=1, c='coral', bc='darkgreen', lw=1, alpha=1, legend=None, texture=None, res=12): '''Build a 2D disc of internal radius r1 and outer radius r2, oriented perpendicular to normal''' ps = vtk.vtkDiskSource() ps.SetInnerRadius(r1) ps.SetOuterRadius(r2) ps.SetRadialResolution(res) ps.SetCircumferentialResolution(res * 4) ps.Update() tr = vtk.vtkTriangleFilter() vu.setInput(tr, ps.GetOutputPort()) tr.Update() axis = np.array(normal) / np.linalg.norm(normal) theta = np.arccos(axis[2]) phi = np.arctan2(axis[1], axis[0]) t = vtk.vtkTransform() t.PostMultiply() t.RotateY(theta * 57.3) t.RotateZ(phi * 57.3) tf = vtk.vtkTransformPolyDataFilter() vu.setInput(tf, tr.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() mapper = vtk.vtkPolyDataMapper() vu.setInput(mapper, pd) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(vc.getColor(c)) # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al actor.GetProperty().SetOpacity(alpha) actor.GetProperty().SetLineWidth(lw) actor.GetProperty().SetInterpolationToFlat() if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(vc.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) if texture: vu.assignTexture(actor, texture) vu.assignPhysicsMethods(actor) vu.assignConvenienceMethods(actor, legend) actor.SetPosition(pos) return actor
def polygon(pos=[0, 0, 0], normal=[0, 0, 1], nsides=6, r=1, c='coral', bc='darkgreen', lw=1, alpha=1, legend=None, texture=None, followcam=False, camera=None): '''Build a 2D polygon of nsides of radius r oriented as normal If followcam=True the polygon will always reorient itself to current camera. ''' ps = vtk.vtkRegularPolygonSource() ps.SetNumberOfSides(nsides) ps.SetRadius(r) ps.SetNormal(-np.array(normal)) ps.Update() tf = vtk.vtkTriangleFilter() vu.setInput(tf, ps.GetOutputPort()) tf.Update() mapper = vtk.vtkPolyDataMapper() vu.setInput(mapper, tf.GetOutputPort()) if followcam: #follow cam actor = vtk.vtkFollower() actor.SetCamera(camera) if not camera: vu.printc('Warning: vtkCamera does not yet exist for polygon', 5) else: actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(vc.getColor(c)) # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al actor.GetProperty().SetOpacity(alpha) actor.GetProperty().SetLineWidth(lw) actor.GetProperty().SetInterpolationToFlat() if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(vc.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) if texture: vu.assignTexture(actor, texture) vu.assignPhysicsMethods(actor) vu.assignConvenienceMethods(actor, legend) actor.SetPosition(pos) return actor
def xyplot(points, title='', c='b', corner=1, lines=False): """ Return a vtkActor that is a plot of 2D points in x and y. Use corner to assign its position: 1=topleft, 2=topright, 3=bottomleft, 4=bottomright. """ c = vc.getColor(c) # allow different codings array_x = vtk.vtkFloatArray() array_y = vtk.vtkFloatArray() array_x.SetNumberOfTuples(len(points)) array_y.SetNumberOfTuples(len(points)) for i, p in enumerate(points): array_x.InsertValue(i, p[0]) array_y.InsertValue(i, p[1]) field = vtk.vtkFieldData() field.AddArray(array_x) field.AddArray(array_y) data = vtk.vtkDataObject() data.SetFieldData(field) plot = vtk.vtkXYPlotActor() plot.AddDataObjectInput(data) plot.SetDataObjectXComponent(0, 0) plot.SetDataObjectYComponent(0, 1) plot.SetXValuesToValue() plot.SetXTitle(title) plot.SetYTitle('') plot.ExchangeAxesOff() plot.PlotPointsOn() if not lines: plot.PlotLinesOff() plot.GetProperty().SetPointSize(5) plot.GetProperty().SetLineWidth(2) plot.SetNumberOfXLabels(3) #not working plot.GetProperty().SetColor(0, 0, 0) plot.GetProperty().SetOpacity(0.7) plot.SetPlotColor(0, c[0], c[1], c[2]) tprop = plot.GetAxisLabelTextProperty() tprop.SetColor(0, 0, 0) tprop.SetOpacity(0.7) tprop.SetFontFamily(0) tprop.BoldOff() tprop.ItalicOff() tprop.ShadowOff() tprop.SetFontSize(3) #not working plot.SetAxisTitleTextProperty(tprop) plot.SetAxisLabelTextProperty(tprop) plot.SetTitleTextProperty(tprop) if corner == 1: plot.GetPositionCoordinate().SetValue(.0, .8, 0) if corner == 2: plot.GetPositionCoordinate().SetValue(.7, .8, 0) if corner == 3: plot.GetPositionCoordinate().SetValue(.0, .0, 0) if corner == 4: plot.GetPositionCoordinate().SetValue(.7, .0, 0) plot.GetPosition2Coordinate().SetValue(.3, .2, 0) return plot
def _colorPoints(plist, cols, r, alpha, legend): if len(plist) > len(cols): vu.printc(("Mismatch in colorPoints()", len(plist), len(cols)), 1) exit() if len(plist) != len(cols): vu.printc( ("Warning: mismatch in colorPoints()", len(plist), len(cols))) src = vtk.vtkPointSource() src.SetNumberOfPoints(len(plist)) src.Update() vertexFilter = vtk.vtkVertexGlyphFilter() vu.setInput(vertexFilter, src.GetOutput()) vertexFilter.Update() pd = vertexFilter.GetOutput() ucols = vtk.vtkUnsignedCharArray() ucols.SetNumberOfComponents(3) ucols.SetName("RGB") for i, p in enumerate(plist): pd.GetPoints().SetPoint(i, p) c = np.array(vc.getColor(cols[i])) * 255 if vu.vtkMV: ucols.InsertNextTuple3(c[0], c[1], c[2]) else: ucols.InsertNextTupleValue(c) pd.GetPointData().SetScalars(ucols) mapper = vtk.vtkPolyDataMapper() vu.setInput(mapper, pd) mapper.ScalarVisibilityOn() actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetInterpolationToFlat() # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al actor.GetProperty().SetOpacity(alpha) actor.GetProperty().SetPointSize(r) return actor
def cutterWidget(obj, outputname='clipped.vtk', c=(0.2, 0.2, 1), alpha=1, bc=(0.7, 0.8, 1), legend=None): '''Pop up a box widget to cut parts of actor. Return largest part.''' apd = vu.polydata(obj) planes = vtk.vtkPlanes() planes.SetBounds(apd.GetBounds()) clipper = vtk.vtkClipPolyData() vu.setInput(clipper, apd) clipper.SetClipFunction(planes) clipper.InsideOutOn() clipper.GenerateClippedOutputOn() # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al act0Mapper = vtk.vtkPolyDataMapper() # the part which stays act0Mapper.SetInputConnection(clipper.GetOutputPort()) act0 = vtk.vtkActor() act0.SetMapper(act0Mapper) act0.GetProperty().SetColor(vc.getColor(c)) act0.GetProperty().SetOpacity(alpha) backProp = vtk.vtkProperty() backProp.SetDiffuseColor(vc.getColor(bc)) backProp.SetOpacity(alpha) act0.SetBackfaceProperty(backProp) #act0 = makeActor(clipper.GetOutputPort()) act0.GetProperty().SetInterpolationToFlat() vu.assignPhysicsMethods(act0) vu.assignConvenienceMethods(act0, legend) act1Mapper = vtk.vtkPolyDataMapper() # the part which is cut away act1Mapper.SetInputConnection(clipper.GetClippedOutputPort()) act1 = vtk.vtkActor() act1.SetMapper(act1Mapper) act1.GetProperty().SetColor(vc.getColor(c)) act1.GetProperty().SetOpacity(alpha / 10.) act1.GetProperty().SetRepresentationToWireframe() act1.VisibilityOn() ren = vtk.vtkRenderer() ren.SetBackground(1, 1, 1) ren.AddActor(act0) ren.AddActor(act1) renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) renWin.SetSize(600, 700) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) istyl = vtk.vtkInteractorStyleSwitch() istyl.SetCurrentStyleToTrackballCamera() iren.SetInteractorStyle(istyl) def SelectPolygons(vobj, event): vobj.GetPlanes(planes) boxWidget = vtk.vtkBoxWidget() boxWidget.OutlineCursorWiresOn() boxWidget.GetSelectedOutlineProperty().SetColor(1, 0, 1) boxWidget.GetOutlineProperty().SetColor(0.1, 0.1, 0.1) boxWidget.GetOutlineProperty().SetOpacity(0.8) boxWidget.SetPlaceFactor(1.05) boxWidget.SetInteractor(iren) vu.setInput(boxWidget, apd) boxWidget.PlaceWidget() boxWidget.AddObserver("InteractionEvent", SelectPolygons) boxWidget.On() vio.printc('\nCutterWidget:\n Move handles to cut parts of the actor', 'm') vio.printc(' Press q to continue, Escape to exit', 'm') vio.printc((" Press X to save file to", outputname), 'm') def cwkeypress(obj, event): key = obj.GetKeySym() if key == "q" or key == "space" or key == "Return": iren.ExitCallback() elif key == "X": confilter = vtk.vtkPolyDataConnectivityFilter() vu.setInput(confilter, clipper.GetOutput()) confilter.SetExtractionModeToLargestRegion() confilter.Update() cpd = vtk.vtkCleanPolyData() vu.setInput(cpd, confilter.GetOutput()) cpd.Update() vio.write(cpd.GetOutput(), outputname) elif key == "Escape": exit(0) iren.Initialize() iren.AddObserver("KeyPressEvent", cwkeypress) iren.Start() boxWidget.Off() return act0
def text(txt, pos=(0, 0, 0), axis=(0, 0, 1), s=1, depth=0.1, c='k', alpha=1, bc=None, followcam=False, texture=None, cam=None): ''' Returns a vtkActor that shows a text in 3D. pos = position in 3D space if an integer is passed [1 -> 8], places text in a corner s = size of text depth = text thickness followcam = True, the text will auto-orient itself to it ''' if isinstance(pos, int): cornerAnnotation = vtk.vtkCornerAnnotation() cornerAnnotation.SetNonlinearFontScaleFactor(s / 3) cornerAnnotation.SetText(pos - 1, txt) cornerAnnotation.GetTextProperty().SetColor(vc.getColor(c)) return cornerAnnotation tt = vtk.vtkVectorText() tt.SetText(txt) tt.Update() ttmapper = vtk.vtkPolyDataMapper() if depth: extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputConnection(tt.GetOutputPort()) extrude.SetExtrusionTypeToVectorExtrusion() extrude.SetVector(0, 0, 1) extrude.SetScaleFactor(depth) ttmapper.SetInputConnection(extrude.GetOutputPort()) else: ttmapper.SetInputConnection(tt.GetOutputPort()) if followcam: #follow cam ttactor = vtk.vtkFollower() ttactor.SetCamera(cam) else: ttactor = vtk.vtkActor() ttactor.SetMapper(ttmapper) ttactor.GetProperty().SetColor(vc.getColor(c)) # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al ttactor.GetProperty().SetOpacity(alpha) nax = np.linalg.norm(axis) if nax: axis = np.array(axis) / nax theta = np.arccos(axis[2]) phi = np.arctan2(axis[1], axis[0]) ttactor.SetScale(s, s, s) ttactor.RotateZ(phi * 57.3) ttactor.RotateY(theta * 57.3) ttactor.SetPosition(pos) if bc: # defines a specific color for the backface backProp = vtk.vtkProperty() backProp.SetDiffuseColor(vc.getColor(bc)) backProp.SetOpacity(alpha) ttactor.SetBackfaceProperty(backProp) if texture: vu.assignTexture(ttactor, texture) vu.assignConvenienceMethods(ttactor, None) vu.assignPhysicsMethods(ttactor) return ttactor
def spheres(centers, r=1, c='r', alpha=1, wire=False, legend=None, texture=None, res=8): ''' Build a (possibly large) set of spheres at centers of radius r. Either c or r can be a list of RGB colors or radii. ''' cisseq = False if vu.isSequence(c): cisseq = True if cisseq: if len(centers) > len(c): vu.printc(("Mismatch in spheres() colors", len(centers), len(c)), 1) exit() if len(centers) != len(c): vu.printc(("Warning: mismatch in spheres() colors", len(centers), len(c))) risseq = False if vu.isSequence(r): risseq = True if risseq: if len(centers) > len(r): vu.printc(("Mismatch in spheres() radius", len(centers), len(r)), 1) exit() if len(centers) != len(r): vu.printc(("Warning: mismatch in spheres() radius", len(centers), len(r))) if cisseq and risseq: vu.printc("Limitation: c and r cannot be both sequences.", 1) exit() src = vtk.vtkSphereSource() if not risseq: src.SetRadius(r) src.SetPhiResolution(res) src.SetThetaResolution(res) src.Update() glyph = vtk.vtkGlyph3D() glyph.SetSourceConnection(src.GetOutputPort()) psrc = vtk.vtkPointSource() psrc.SetNumberOfPoints(len(centers)) psrc.Update() pd = psrc.GetOutput() vpts = pd.GetPoints() if cisseq: glyph.SetColorModeToColorByScalar() ucols = vtk.vtkUnsignedCharArray() ucols.SetNumberOfComponents(3) ucols.SetName("colors") for i, p in enumerate(centers): vpts.SetPoint(i, p) cc = np.array(vc.getColor(c[i])) * 255 if vu.vtkMV: ucols.InsertNextTuple3(cc[0], cc[1], cc[2]) else: ucols.InsertNextTupleValue(cc) pd.GetPointData().SetScalars(ucols) glyph.ScalingOff() elif risseq: glyph.SetScaleModeToScaleByScalar() urads = vtk.vtkFloatArray() urads.SetName("scales") for i, p in enumerate(centers): vpts.SetPoint(i, p) urads.InsertNextValue(r[i]) pd.GetPointData().SetScalars(urads) else: for i, p in enumerate(centers): vpts.SetPoint(i, p) vu.setInput(glyph, pd) glyph.Update() mapper = vtk.vtkPolyDataMapper() vu.setInput(mapper, glyph.GetOutput()) if cisseq: mapper.ScalarVisibilityOn() else: mapper.ScalarVisibilityOff() actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetInterpolationToPhong() # check if color string contains a float, in this case ignore alpha al = vc.getAlpha(c) if al: alpha = al actor.GetProperty().SetOpacity(alpha) if not cisseq: if texture is not None: vu.assignTexture(actor, texture) mapper.ScalarVisibilityOff() else: actor.GetProperty().SetColor(vc.getColor(c)) vu.assignConvenienceMethods(actor, legend) return actor