def lines(plist0, plist1=None, lw=1, c='r', alpha=1, dotted=False, legend=None): ''' Build the line segments between two lists of points `plist0` and `plist1`. `plist0` can be also passed in the form ``[[point1, point2], ...]``. .. hint:: Example: `fitspheres2.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/fitspheres2.py>`_ ''' if plist1 is not None: plist0 = list(zip(plist0, plist1)) polylns = vtk.vtkAppendPolyData() for twopts in plist0: lineSource = vtk.vtkLineSource() lineSource.SetPoint1(twopts[0]) lineSource.SetPoint2(twopts[1]) polylns.AddInputConnection(lineSource.GetOutputPort()) polylns.Update() actor = Actor(polylns.GetOutput(), c, alpha, legend=legend) actor.GetProperty().SetLineWidth(lw) if dotted: actor.GetProperty().SetLineStipplePattern(0xf0f0) actor.GetProperty().SetLineStippleRepeatFactor(1) return actor
def _colorPoints(plist, cols, r, alpha, legend): n = len(plist) if n > len(cols): colors.printc("Mismatch in colorPoints()", n, len(cols), c=1) exit() if n != len(cols): colors.printc("Warning: mismatch in colorPoints()", n, len(cols)) src = vtk.vtkPointSource() src.SetNumberOfPoints(n) src.Update() vertexFilter = vtk.vtkVertexGlyphFilter() vertexFilter.SetInputData(src.GetOutput()) vertexFilter.Update() pd = vertexFilter.GetOutput() ucols = vtk.vtkUnsignedCharArray() ucols.SetNumberOfComponents(3) ucols.SetName("RGB") for i, p in enumerate(plist): c = np.array(colors.getColor(cols[i])) * 255 ucols.InsertNextTuple3(c[0], c[1], c[2]) pd.GetPoints().SetData(numpy_to_vtk(plist, deep=True)) pd.GetPointData().SetScalars(ucols) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(pd) mapper.ScalarVisibilityOn() actor = Actor() #vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetInterpolationToFlat() actor.GetProperty().SetOpacity(alpha) actor.GetProperty().SetPointSize(r) return actor
def _colorPoints(plist, cols, r, alpha): n = len(plist) if n > len(cols): colors.printc("~times Error: mismatch in colorPoints()", n, len(cols), c=1) exit() if n != len(cols): colors.printc("~lightning Warning: mismatch in colorPoints()", n, len(cols)) src = vtk.vtkPointSource() src.SetNumberOfPoints(n) src.Update() vgf = vtk.vtkVertexGlyphFilter() vgf.SetInputData(src.GetOutput()) vgf.Update() pd = vgf.GetOutput() ucols = vtk.vtkUnsignedCharArray() ucols.SetNumberOfComponents(3) ucols.SetName("pointsRGB") for i in range(len(plist)): c = np.array(colors.getColor(cols[i])) * 255 ucols.InsertNextTuple3(c[0], c[1], c[2]) pd.GetPoints().SetData(numpy_to_vtk(plist, deep=True)) pd.GetPointData().SetScalars(ucols) actor = Actor(pd, c, alpha) actor.mapper.ScalarVisibilityOn() actor.GetProperty().SetInterpolationToFlat() actor.GetProperty().SetPointSize(r) settings.collectable_actors.append(actor) return actor
def Lines(plist0, plist1=None, lw=1, c="r", alpha=1, dotted=False): """ Build the line segments between two lists of points `plist0` and `plist1`. `plist0` can be also passed in the form ``[[point1, point2], ...]``. |lines| .. hint:: |fitspheres2.py|_ """ if plist1 is not None: plist0 = list(zip(plist0, plist1)) polylns = vtk.vtkAppendPolyData() for twopts in plist0: lineSource = vtk.vtkLineSource() lineSource.SetPoint1(twopts[0]) lineSource.SetPoint2(twopts[1]) polylns.AddInputConnection(lineSource.GetOutputPort()) polylns.Update() actor = Actor(polylns.GetOutput(), c, alpha) actor.GetProperty().SetLineWidth(lw) if dotted: actor.GetProperty().SetLineStipplePattern(0xF0F0) actor.GetProperty().SetLineStippleRepeatFactor(1) return actor
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 * 6) # ~2pi ps.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() tf.SetInputData(ps.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(pd) actor = Actor() # vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.getColor(c)) # check if color string contains a float, in this case ignore alpha al = colors._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(colors.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) if texture: actor.texture(texture) actor.SetPosition(pos) return actor
def Disc( pos=(0, 0, 0), normal=(0, 0, 1), r1=0.5, r2=1, c="coral", bc="darkgreen", lw=1, alpha=1, res=12, resphi=None, ): """ Build a 2D disc of internal radius `r1` and outer radius `r2`, oriented perpendicular to `normal`. |Disk| """ ps = vtk.vtkDiskSource() ps.SetInnerRadius(r1) ps.SetOuterRadius(r2) ps.SetRadialResolution(res) if not resphi: resphi = 6 * res ps.SetCircumferentialResolution(resphi) ps.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(np.rad2deg(theta)) t.RotateZ(np.rad2deg(phi)) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(ps.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(pd) actor = Actor() # vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.getColor(c)) 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(colors.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) actor.SetPosition(pos) settings.collectable_actors.append(actor) 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() tf.SetInputConnection(ps.GetOutputPort()) tf.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(tf.GetOutputPort()) if followcam: # follow cam actor = vtk.vtkFollower() actor.SetCamera(camera) if not camera: colors.printc('Warning: vtkCamera does not yet exist for polygon', c=5) else: actor = Actor() # vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.getColor(c)) # check if color string contains a float, in this case ignore alpha al = colors._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(colors.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) if texture: actor.texture(texture) actor.SetPosition(pos) return actor
def Line(p0, p1=None, lw=1, c="r", alpha=1, dotted=False, res=None): """ Build the line segment between points `p0` and `p1`. If `p0` is a list of points returns the line connecting them. A 2D set of coords can also be passed as p0=[x..], p1=[y..]. :param lw: line width. :param c: color name, number, or list of [R,G,B] colors. :type c: int, str, list :param float alpha: transparency in range [0,1]. :param bool dotted: draw a dotted line """ # detect if user is passing a 2D ist of points as p0=xlist, p1=ylist: if len(p0) > 3: if not utils.isSequence(p0[0]) and not utils.isSequence( p1[0]) and len(p0) == len(p1): # assume input is 2D xlist, ylist p0 = list(zip(p0, p1)) p1 = None # detect if user is passing a list of points: if utils.isSequence(p0[0]): ppoints = vtk.vtkPoints() # Generate the polyline dim = len((p0[0])) if dim == 2: for i, p in enumerate(p0): ppoints.InsertPoint(i, p[0], p[1], 0) else: ppoints.SetData(numpy_to_vtk(p0, deep=True)) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(len(p0)) for i in range(len(p0)): lines.InsertCellPoint(i) poly = vtk.vtkPolyData() poly.SetPoints(ppoints) poly.SetLines(lines) else: # or just 2 points to link lineSource = vtk.vtkLineSource() lineSource.SetPoint1(p0) lineSource.SetPoint2(p1) if res: lineSource.SetResolution(res) lineSource.Update() poly = lineSource.GetOutput() actor = Actor(poly, c, alpha) actor.GetProperty().SetLineWidth(lw) if dotted: actor.GetProperty().SetLineStipplePattern(0xF0F0) actor.GetProperty().SetLineStippleRepeatFactor(1) actor.base = np.array(p0) actor.top = np.array(p1) settings.collectable_actors.append(actor) return actor
def Polygon(pos=(0, 0, 0), normal=(0, 0, 1), nsides=6, r=1, c="coral", bc="darkgreen", lw=1, alpha=1, followcam=False): """ Build a 2D polygon of `nsides` of radius `r` oriented as `normal`. :param followcam: if `True` the text will auto-orient itself to the active camera. A ``vtkCamera`` object can also be passed. :type followcam: bool, vtkCamera |Polygon| """ ps = vtk.vtkRegularPolygonSource() ps.SetNumberOfSides(nsides) ps.SetRadius(r) ps.SetNormal(-np.array(normal)) ps.Update() tf = vtk.vtkTriangleFilter() tf.SetInputConnection(ps.GetOutputPort()) tf.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(tf.GetOutputPort()) if followcam: import vtkplotter.plotter as plt actor = vtk.vtkFollower() if isinstance(followcam, vtk.vtkCamera): actor.SetCamera(followcam) else: actor.SetCamera(plt._plotter_instance.camera) else: actor = Actor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.getColor(c)) 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(colors.getColor(bc)) backProp.SetOpacity(alpha) actor.SetBackfaceProperty(backProp) actor.SetPosition(pos) return actor
def Ellipsoid(pos=(0, 0, 0), axis1=(1, 0, 0), axis2=(0, 2, 0), axis3=(0, 0, 3), c="c", alpha=1, res=24): """ Build a 3D ellipsoid centered at position `pos`. .. note:: `axis1` and `axis2` are only used to define sizes and one azimuth angle. |projectsphere| """ elliSource = vtk.vtkSphereSource() elliSource.SetThetaResolution(res) elliSource.SetPhiResolution(res) elliSource.Update() l1 = np.linalg.norm(axis1) l2 = np.linalg.norm(axis2) l3 = np.linalg.norm(axis3) axis1 = np.array(axis1) / l1 axis2 = np.array(axis2) / l2 axis3 = np.array(axis3) / l3 angle = np.arcsin(np.dot(axis1, axis2)) theta = np.arccos(axis3[2]) phi = np.arctan2(axis3[1], axis3[0]) t = vtk.vtkTransform() t.PostMultiply() t.Scale(l1, l2, l3) t.RotateX(np.rad2deg(angle)) t.RotateY(np.rad2deg(theta)) t.RotateZ(np.rad2deg(phi)) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(elliSource.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, alpha=alpha) actor.GetProperty().BackfaceCullingOn() actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(pos) actor.base = -np.array(axis1) / 2 + pos actor.top = np.array(axis1) / 2 + pos settings.collectable_actors.append(actor) return actor
def tube(points, r=1, c='r', alpha=1, legend=None, res=12): '''Build a tube of radius `r` along line defined by a set of points. .. hint:: Example: `ribbon.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/ribbon.py>`_ .. image:: https://user-images.githubusercontent.com/32848391/50738851-be9bcb00-11d8-11e9-80ee-bd73c1c29c06.jpg ''' ppoints = vtk.vtkPoints() # Generate the polyline ppoints.SetData(numpy_to_vtk(points, deep=True)) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(len(points)) for i in range(len(points)): lines.InsertCellPoint(i) poly = vtk.vtkPolyData() poly.SetPoints(ppoints) poly.SetLines(lines) tuf = vtk.vtkTubeFilter() tuf.SetNumberOfSides(res) tuf.SetInputData(poly) tuf.SetRadius(r) tuf.CappingOn() tuf.Update() poly = tuf.GetOutput() actor = Actor(poly, c, alpha, legend=legend) actor.GetProperty().SetInterpolationToPhong() actor.base = np.array(points[0]) actor.top = np.array(points[-1]) return actor
def _loadFile(filename, c, alpha, wire, bc, legend, texture, smoothing, threshold, connectivity): fl = filename.lower() if legend is True: legend = os.path.basename(filename) if fl.endswith('.xml') or fl.endswith( '.xml.gz'): # Fenics tetrahedral file actor = loadDolfin(filename, c, alpha, wire, bc, legend) elif fl.endswith('.neutral') or fl.endswith( '.neu'): # neutral tetrahedral file actor = loadNeutral(filename, c, alpha, wire, bc, legend) elif fl.endswith('.gmsh'): # gmesh file actor = loadGmesh(filename, c, alpha, wire, bc, legend) elif fl.endswith('.pcd'): # PCL point-cloud format actor = loadPCD(filename, c, alpha, legend) elif fl.endswith('.3ds'): # PCL point-cloud format actor = load3DS(filename, legend) elif fl.endswith('.tif') or fl.endswith('.slc') or fl.endswith('.vti'): # tiff stack or slc or vti img = loadImageData(filename) actor = utils.isosurface(img, c, alpha, wire, bc, legend, texture, smoothing, threshold, connectivity) elif fl.endswith('.png') or fl.endswith('.jpg') or fl.endswith('.jpeg'): actor = load2Dimage(filename, alpha) else: poly = loadPolyData(filename) if not poly: colors.printc('Unable to load', filename, c=1) return None actor = Actor(poly, c, alpha, wire, bc, legend, texture) if fl.endswith('.txt') or fl.endswith('.xyz'): actor.GetProperty().SetPointSize(4) actor.filename = filename return actor
def Torus(pos=(0, 0, 0), r=1, thickness=0.1, axis=(0, 0, 1), c="khaki", alpha=1, res=30): """ Build a torus of specified outer radius `r` internal radius `thickness`, centered at `pos`. .. hint:: |gas| |gas.py|_ """ rs = vtk.vtkParametricTorus() rs.SetRingRadius(r) rs.SetCrossSectionRadius(thickness) pfs = vtk.vtkParametricFunctionSource() pfs.SetParametricFunction(rs) pfs.SetUResolution(res * 3) pfs.SetVResolution(res) pfs.Update() nax = np.linalg.norm(axis) if nax: axis = np.array(axis) / nax theta = np.arccos(axis[2]) phi = np.arctan2(axis[1], axis[0]) t = vtk.vtkTransform() t.PostMultiply() t.RotateY(np.rad2deg(theta)) t.RotateZ(np.rad2deg(phi)) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(pfs.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c, alpha) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(pos) settings.collectable_actors.append(actor) return actor
def cone(pos=[0, 0, 0], r=1, height=1, axis=[0, 0, 1], c='dg', alpha=1, legend=None, texture=None, res=48): ''' Build a cone of specified radius `r` and `height`, centered at `pos`. ''' con = vtk.vtkConeSource() con.SetResolution(res) con.SetRadius(r) con.SetHeight(height) con.SetDirection(axis) con.Update() actor = Actor(con.GetOutput(), c, alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(pos) v = utils.norm(axis) * height / 2 actor.base = pos - v actor.top = pos + v return actor
def tube(points, r=1, c='r', alpha=1, legend=None, res=12): '''Build a tube of radius r along line defined py points.''' ppoints = vtk.vtkPoints() # Generate the polyline ppoints.SetData(numpy_to_vtk(points, deep=True)) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(len(points)) for i in range(len(points)): lines.InsertCellPoint(i) poly = vtk.vtkPolyData() poly.SetPoints(ppoints) poly.SetLines(lines) tuf = vtk.vtkTubeFilter() tuf.SetNumberOfSides(res) tuf.SetInputData(poly) tuf.SetRadius(r) tuf.CappingOn() tuf.Update() poly = tuf.GetOutput() actor = Actor(poly, c, alpha, legend=legend) actor.GetProperty().SetInterpolationToPhong() actor.base = np.array(points[0]) actor.top = np.array(points[-1]) return actor
def grid(pos=[0, 0, 0], normal=[0, 0, 1], sx=1, sy=1, c='g', bc='darkgreen', lw=1, alpha=1, legend=None, resx=10, resy=10): '''Return a grid plane. .. hint:: Example: `brownian2D.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/brownian2D.py>`_ .. image:: https://user-images.githubusercontent.com/32848391/50738948-73ce8300-11d9-11e9-8ef6-fc4f64c4a9ce.gif ''' ps = vtk.vtkPlaneSource() ps.SetResolution(resx, resy) ps.Update() poly0 = ps.GetOutput() t0 = vtk.vtkTransform() t0.Scale(sx, sy, 1) tf0 = vtk.vtkTransformPolyDataFilter() tf0.SetInputData(poly0) tf0.SetTransform(t0) tf0.Update() poly = tf0.GetOutput() 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() tf.SetInputData(poly) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, bc=bc, alpha=alpha, legend=legend) actor.GetProperty().SetRepresentationToWireframe() actor.GetProperty().SetLineWidth(lw) actor.SetPosition(pos) actor.PickableOff() return actor
def Grid( pos=(0, 0, 0), normal=(0, 0, 1), sx=1, sy=1, c="g", bc="darkgreen", lw=1, alpha=1, resx=10, resy=10, ): """Return a grid plane. .. hint:: |brownian2D| |brownian2D.py|_ """ ps = vtk.vtkPlaneSource() ps.SetResolution(resx, resy) ps.Update() poly0 = ps.GetOutput() t0 = vtk.vtkTransform() t0.Scale(sx, sy, 1) tf0 = vtk.vtkTransformPolyDataFilter() tf0.SetInputData(poly0) tf0.SetTransform(t0) tf0.Update() poly = tf0.GetOutput() 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(np.rad2deg(theta)) t.RotateZ(np.rad2deg(phi)) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(poly) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, bc=bc, alpha=alpha) actor.GetProperty().SetRepresentationToWireframe() actor.GetProperty().SetLineWidth(lw) actor.SetPosition(pos) settings.collectable_actors.append(actor) return actor
def ellipsoid(pos=[0, 0, 0], axis1=[1, 0, 0], axis2=[0, 2, 0], axis3=[0, 0, 3], c='c', alpha=1, legend=None, texture=None, res=24): """ Build a 3D ellipsoid centered at position `pos`. .. note:: `axis1` and `axis2` are only used to define sizes and one azimuth angle. """ elliSource = vtk.vtkSphereSource() elliSource.SetThetaResolution(res) elliSource.SetPhiResolution(res) elliSource.Update() l1 = np.linalg.norm(axis1) l2 = np.linalg.norm(axis2) l3 = np.linalg.norm(axis3) axis1 = np.array(axis1) / l1 axis2 = np.array(axis2) / l2 axis3 = np.array(axis3) / l3 angle = np.arcsin(np.dot(axis1, axis2)) theta = np.arccos(axis3[2]) phi = np.arctan2(axis3[1], axis3[0]) t = vtk.vtkTransform() t.PostMultiply() t.Scale(l1, l2, l3) t.RotateX(angle * 57.3) t.RotateY(theta * 57.3) t.RotateZ(phi * 57.3) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(elliSource.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, alpha=alpha, legend=legend, texture=texture) actor.GetProperty().BackfaceCullingOn() actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(pos) return actor
def cylinder(pos=[0, 0, 0], r=1, height=1, axis=[0, 0, 1], c='teal', wire=0, alpha=1, legend=None, texture=None, res=24): ''' Build a cylinder of specified height and radius r, centered at pos. If pos is a list of 2 points, e.g. pos=[v1,v2], build a cylinder with base centered at v1 and top at v2. [**Example1**](https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/gyroscope1.py) [**Example2**](https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/turing.py) ''' if utils.isSequence(pos[0]): # assume user is passing pos=[base, top] base = np.array(pos[0]) top = np.array(pos[1]) pos = (base + top) / 2 height = np.linalg.norm(top - base) axis = top - base axis = utils.norm(axis) else: axis = utils.norm(axis) base = pos - axis * height / 2 top = pos + axis * height / 2 cyl = vtk.vtkCylinderSource() cyl.SetResolution(res) cyl.SetRadius(r) cyl.SetHeight(height) cyl.Update() theta = np.arccos(axis[2]) phi = np.arctan2(axis[1], axis[0]) t = vtk.vtkTransform() t.PostMultiply() t.RotateX(90) # put it along Z t.RotateY(theta * 57.3) t.RotateZ(phi * 57.3) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(cyl.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c, alpha, wire, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(pos) actor.base = base actor.top = top return actor
def line(p0, p1=None, lw=1, c='r', alpha=1, dotted=False, legend=None): ''' Build the line segment between points `p0` and `p1`. If `p0` is a list of points returns the line connecting them. :param lw: line width. :param c: color name, number, or list of [R,G,B] colors. :type c: int, str, list :param float alpha: transparency in range [0,1]. :param bool dotted: draw a dotted line ''' # detect if user is passing a list of points: if utils.isSequence(p0[0]): ppoints = vtk.vtkPoints() # Generate the polyline dim = len((p0[0])) if dim == 2: for i in range(len(p0)): p = p0[i] ppoints.InsertPoint(i, p[0], p[1], 0) else: ppoints.SetData(numpy_to_vtk(p0, deep=True)) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(len(p0)) for i in range(len(p0)): lines.InsertCellPoint(i) poly = vtk.vtkPolyData() poly.SetPoints(ppoints) poly.SetLines(lines) else: # or just 2 points to link lineSource = vtk.vtkLineSource() lineSource.SetPoint1(p0) lineSource.SetPoint2(p1) lineSource.Update() poly = lineSource.GetOutput() actor = Actor(poly, c, alpha, legend=legend) actor.GetProperty().SetLineWidth(lw) if dotted: actor.GetProperty().SetLineStipplePattern(0xf0f0) actor.GetProperty().SetLineStippleRepeatFactor(1) actor.base = np.array(p0) actor.top = np.array(p1) return actor
def Lines(startPoints, endPoints=None, scale=1, lw=1, c=None, alpha=1, dotted=False): """ Build the line segments between two lists of points `startPoints` and `endPoints`. `startPoints` can be also passed in the form ``[[point1, point2], ...]``. :param float scale: apply a rescaling factor to the length |lines| .. hint:: |fitspheres2.py|_ """ if endPoints is not None: startPoints = list(zip(startPoints, endPoints)) polylns = vtk.vtkAppendPolyData() for twopts in startPoints: lineSource = vtk.vtkLineSource() lineSource.SetPoint1(twopts[0]) if scale != 1: vers = (np.array(twopts[1]) - twopts[0]) * scale pt2 = np.array(twopts[0]) + vers else: pt2 = twopts[1] lineSource.SetPoint2(pt2) polylns.AddInputConnection(lineSource.GetOutputPort()) polylns.Update() actor = Actor(polylns.GetOutput(), c, alpha) actor.GetProperty().SetLineWidth(lw) if dotted: actor.GetProperty().SetLineStipplePattern(0xF0F0) actor.GetProperty().SetLineStippleRepeatFactor(1) settings.collectable_actors.append(actor) return actor
def spline(points, smooth=0.5, degree=2, s=2, c='b', alpha=1., nodes=False, legend=None, res=20): ''' Return a vtkActor for a spline that doesnt necessarly pass exactly throught all points. Options: smooth, smoothing factor: 0 = interpolate points exactly, 1 = average point positions degree = degree of the spline (1<degree<5) nodes = True shows also original the points [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/tutorial.py) ![rspline](https://user-images.githubusercontent.com/32848391/35976041-15781de8-0cdf-11e8-997f-aeb725bc33cc.png) ''' try: from scipy.interpolate import splprep, splev except ImportError: vc.printc('Warning: ..scipy not installed, using vtkCardinalSpline instead.', c=5) return _vtkspline(points, s, c, alpha, nodes, legend, res) Nout = len(points)*res # Number of points on the spline points = np.array(points) minx, miny, minz = np.min(points, axis=0) maxx, maxy, maxz = np.max(points, axis=0) maxb = max(maxx-minx, maxy-miny, maxz-minz) smooth *= maxb/2 # must be in absolute units x, y, z = points[:, 0], points[:, 1], points[:, 2] tckp, _ = splprep([x, y, z], task=0, s=smooth, k=degree) # find the knots # evaluate spline, including interpolated points: xnew, ynew, znew = splev(np.linspace(0, 1, Nout), tckp) ppoints = vtk.vtkPoints() # Generate the polyline for the spline profileData = vtk.vtkPolyData() ppoints.SetData(numpy_to_vtk( list(zip(xnew, ynew, znew)), deep=True)) lines = vtk.vtkCellArray() # Create the polyline lines.InsertNextCell(Nout) for i in range(Nout): lines.InsertCellPoint(i) profileData.SetPoints(ppoints) profileData.SetLines(lines) actline = Actor(profileData, c=c, alpha=alpha, legend=legend) actline.GetProperty().SetLineWidth(s) if nodes: actnodes = vs.points(points, r=5, c=c, alpha=alpha) ass = Assembly([actline, actnodes], legend=legend) return ass else: return actline
def arrow(startPoint, endPoint, c='r', s=None, alpha=1, legend=None, texture=None, res=12, rwSize=(800, 800)): ''' Build a 3D arrow from `startPoint` to `endPoint` of section size `s`, expressed as the fraction of the window size. .. note:: If ``s=None`` the arrow is scaled proportionally to its length, otherwise it represents the fraction of the window size. ''' axis = np.array(endPoint) - np.array(startPoint) length = np.linalg.norm(axis) if not length: return None axis = axis / length theta = np.arccos(axis[2]) phi = np.arctan2(axis[1], axis[0]) arr = vtk.vtkArrowSource() arr.SetShaftResolution(res) arr.SetTipResolution(res) if s: sz = 0.02 arr.SetTipRadius(sz) arr.SetShaftRadius(sz / 1.75) arr.SetTipLength(sz * 15) arr.Update() t = vtk.vtkTransform() t.RotateZ(phi * 57.3) t.RotateY(theta * 57.3) t.RotateY(-90) # put it along Z if s: w, h = rwSize sz = (w + h) / 2 * s t.Scale(length, sz, sz) else: t.Scale(length, length, length) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(arr.GetOutput()) tf.SetTransform(t) tf.Update() actor = Actor(tf.GetOutput(), c, alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(startPoint) actor.DragableOff() actor.PickableOff() actor.base = np.array(startPoint) actor.top = np.array(endPoint) return actor
def _buildactor(d): vertices = d['points'] cells = None lines = None keys = d.keys() if 'cells' in keys: cells = d['cells'] if 'lines' in keys: lines = d['lines'] poly = utils.buildPolyData(vertices, cells, lines) act = Actor(poly) loadcommon(act, d) act.mapper.ScalarVisibilityOff() if 'celldata' in keys: for csc, cscname in d['celldata']: act.addCellScalars(csc, cscname) if not 'normal' in cscname.lower(): act.scalars(cscname) # activate if 'pointdata' in keys: for psc, pscname in d['pointdata']: act.addPointScalars(psc, pscname) if not 'normal' in pscname.lower(): act.scalars(pscname) # activate prp = act.GetProperty() if 'specular' in keys: prp.SetSpecular(d['specular']) if 'specularpower' in keys: prp.SetSpecularPower(d['specularpower']) if 'specularcolor' in keys: prp.SetSpecularColor(d['specularcolor']) if 'shading' in keys: prp.SetInterpolation(d['shading']) if 'alpha' in keys: prp.SetOpacity(d['alpha']) if 'opacity' in keys: prp.SetOpacity(d['opacity']) # synomym if 'pointsize' in keys and d['pointsize']: prp.SetPointSize(d['pointsize']) if 'texture' in keys and d['texture']: act.texture(d['texture']) if 'linewidth' in keys and d['linewidth']: act.lineWidth(d['linewidth']) if 'linecolor' in keys and d['linecolor']: act.lineColor(d['linecolor']) if 'representation' in keys: prp.SetRepresentation(d['representation']) if 'color' in keys and d['color']: act.color(d['color']) if 'backColor' in keys and d['backColor']: act.backColor(d['backColor']) if 'activedata' in keys and d['activedata'] is not None: act.mapper.ScalarVisibilityOn() if d['activedata'][0] == 'celldata': poly.GetCellData().SetActiveScalars(d['activedata'][1]) if d['activedata'][0] == 'pointdata': poly.GetPointData().SetActiveScalars(d['activedata'][1]) return act
def hyperboloid(pos=[0, 0, 0], a2=1, value=0.5, height=1, axis=[0, 0, 1], c='magenta', alpha=1, legend=None, texture=None, res=100): ''' Build a hyperboloid of specified aperture `a2` and `height`, centered at `pos`. Full volumetric expression is: :math:`F(x,y,z)=a_0x^2+a_1y^2+a_2z^2+a_3xy+a_4yz+a_5xz+ a_6x+a_7y+a_8z+a_9` .. hint:: Example: `mesh_bands.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/mesh_bands.py>`_ .. image:: https://user-images.githubusercontent.com/32848391/51211548-26a78b00-1916-11e9-9306-67b677d1be3a.png ''' q = vtk.vtkQuadric() q.SetCoefficients(2, 2, -1 / a2, 0, 0, 0, 0, 0, 0, 0) # F(x,y,z) = a0*x^2 + a1*y^2 + a2*z^2 # + a3*x*y + a4*y*z + a5*x*z # + a6*x + a7*y + a8*z +a9 sample = vtk.vtkSampleFunction() sample.SetSampleDimensions(res, res, res) sample.SetImplicitFunction(q) contours = vtk.vtkContourFilter() contours.SetInputConnection(sample.GetOutputPort()) contours.GenerateValues(1, value, value) contours.Update() axis = np.array(axis) / np.linalg.norm(axis) 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) t.Scale(1, 1, height) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(contours.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, alpha=alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.GetMapper().ScalarVisibilityOff() actor.SetPosition(pos) return actor
def Points(plist, r=5, c="gray", alpha=1): """ Build a point ``Actor`` for a list of points. :param float r: point radius. :param c: color name, number, or list of [R,G,B] colors of same length as plist. :type c: int, str, list :param float alpha: transparency in range [0,1]. .. hint:: |lorenz| |lorenz.py|_ """ n = len(plist) if n == 0: return None elif n == 3: # assume plist is in the format [all_x, all_y, all_z] if utils.isSequence(plist[0]) and len(plist[0]) > 3: plist = list(zip(plist[0], plist[1], plist[2])) elif n == 2: # assume plist is in the format [all_x, all_y, 0] if utils.isSequence(plist[0]) and len(plist[0]) > 3: plist = list(zip(plist[0], plist[1], [0] * len(plist[0]))) if utils.isSequence(c) and utils.isSequence(c[0]) and len(c[0]) == 3: return _colorPoints(plist, c, r, alpha) n = len(plist) # refresh sourcePoints = vtk.vtkPoints() sourceVertices = vtk.vtkCellArray() is3d = len(plist[0]) > 2 if is3d: for pt in plist: aid = sourcePoints.InsertNextPoint(pt) sourceVertices.InsertNextCell(1) sourceVertices.InsertCellPoint(aid) else: for pt in plist: aid = sourcePoints.InsertNextPoint(pt[0], pt[1], 0) sourceVertices.InsertNextCell(1) sourceVertices.InsertCellPoint(aid) pd = vtk.vtkPolyData() pd.SetPoints(sourcePoints) pd.SetVerts(sourceVertices) if n == 1: # passing just one point pd.GetPoints().SetPoint(0, [0, 0, 0]) else: pd.GetPoints().SetData(numpy_to_vtk(plist, deep=True)) actor = Actor(pd, c, alpha) actor.GetProperty().SetPointSize(r) if n == 1: actor.SetPosition(plist[0]) return actor
def helix(startPoint=[0, 0, 0], endPoint=[1, 1, 1], coils=20, r=None, thickness=None, c='grey', alpha=1, legend=None, texture=None): ''' Build a spring of specified nr of coils between startPoint and endPoint. [**Example1**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/spring.py) [**Example2**](https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/gyroscope1.py) [**Example3**](https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/multiple_pendulum.py) ''' diff = endPoint - np.array(startPoint) length = np.linalg.norm(diff) if not length: return None if not r: r = length / 20 trange = np.linspace(0, length, num=50 * coils) om = 6.283 * (coils - .5) / length pts = [[r * np.cos(om * t), r * np.sin(om * t), t] for t in trange] pts = [[0, 0, 0]] + pts + [[0, 0, length]] diff = diff / length theta = np.arccos(diff[2]) phi = np.arctan2(diff[1], diff[0]) sp = line(pts).polydata(False) t = vtk.vtkTransform() t.RotateZ(phi * 57.3) t.RotateY(theta * 57.3) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(sp) tf.SetTransform(t) tf.Update() tuf = vtk.vtkTubeFilter() tuf.SetNumberOfSides(12) tuf.CappingOn() tuf.SetInputData(tf.GetOutput()) if not thickness: thickness = r / 10 tuf.SetRadius(thickness) tuf.Update() poly = tuf.GetOutput() actor = Actor(poly, c, alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(startPoint) actor.base = np.array(startPoint) actor.top = np.array(endPoint) return actor
def helix(startPoint=[0, 0, 0], endPoint=[1, 0, 0], coils=20, r=None, thickness=None, c='grey', alpha=1, legend=None, texture=None): ''' Build a spring of specified nr of `coils` between `startPoint` and `endPoint`. .. hint:: Example: `aspring.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/advanced/aspring.py>`_ .. image:: https://user-images.githubusercontent.com/32848391/36788885-e97e80ae-1c8f-11e8-8b8f-ffc43dad1eb1.gif ''' diff = endPoint - np.array(startPoint) length = np.linalg.norm(diff) if not length: return None if not r: r = length / 20 trange = np.linspace(0, length, num=50 * coils) om = 6.283 * (coils - .5) / length pts = [[r * np.cos(om * t), r * np.sin(om * t), t] for t in trange] pts = [[0, 0, 0]] + pts + [[0, 0, length]] diff = diff / length theta = np.arccos(diff[2]) phi = np.arctan2(diff[1], diff[0]) sp = line(pts).polydata(False) t = vtk.vtkTransform() t.RotateZ(phi * 57.3) t.RotateY(theta * 57.3) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(sp) tf.SetTransform(t) tf.Update() tuf = vtk.vtkTubeFilter() tuf.SetNumberOfSides(12) tuf.CappingOn() tuf.SetInputData(tf.GetOutput()) if not thickness: thickness = r / 10 tuf.SetRadius(thickness) tuf.Update() poly = tuf.GetOutput() actor = Actor(poly, c, alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.SetPosition(startPoint) actor.base = np.array(startPoint) actor.top = np.array(endPoint) return actor
def paraboloid(pos=[0, 0, 0], r=1, height=1, axis=[0, 0, 1], c='cyan', alpha=1, legend=None, texture=None, res=100): ''' Build a paraboloid of specified height and radius `r`, centered at `pos`. .. note:: Full volumetric expression is: :math:`F(x,y,z)=a_0x^2+a_1y^2+a_2z^2+a_3xy+a_4yz+a_5xz+ a_6x+a_7y+a_8z+a_9` .. image:: https://user-images.githubusercontent.com/32848391/51211547-260ef480-1916-11e9-95f6-4a677e37e355.png ''' quadric = vtk.vtkQuadric() quadric.SetCoefficients(1, 1, 0, 0, 0, 0, 0, 0, height / 4, 0) # F(x,y,z) = a0*x^2 + a1*y^2 + a2*z^2 # + a3*x*y + a4*y*z + a5*x*z # + a6*x + a7*y + a8*z +a9 sample = vtk.vtkSampleFunction() sample.SetSampleDimensions(res, res, res) sample.SetImplicitFunction(quadric) contours = vtk.vtkContourFilter() contours.SetInputConnection(sample.GetOutputPort()) contours.GenerateValues(1, .01, .01) contours.Update() axis = np.array(axis) / np.linalg.norm(axis) 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) t.Scale(r, r, r) tf = vtk.vtkTransformPolyDataFilter() tf.SetInputData(contours.GetOutput()) tf.SetTransform(t) tf.Update() pd = tf.GetOutput() actor = Actor(pd, c=c, alpha=alpha, legend=legend, texture=texture) actor.GetProperty().SetInterpolationToPhong() actor.GetMapper().ScalarVisibilityOff() actor.SetPosition(pos) return actor
def _vtkspline(points, s, c, alpha, nodes, legend, res): numberOfOutputPoints = len(points)*res # Number of points on the spline numberOfInputPoints = len(points) # One spline for each direction. aSplineX = vtk.vtkCardinalSpline() # interpolate the x values aSplineY = vtk.vtkCardinalSpline() # interpolate the y values aSplineZ = vtk.vtkCardinalSpline() # interpolate the z values inputPoints = vtk.vtkPoints() for i in range(0, numberOfInputPoints): x = points[i][0] y = points[i][1] z = points[i][2] aSplineX.AddPoint(i, x) aSplineY.AddPoint(i, y) aSplineZ.AddPoint(i, z) inputPoints.InsertPoint(i, x, y, z) inputData = vtk.vtkPolyData() inputData.SetPoints(inputPoints) points = vtk.vtkPoints() profileData = vtk.vtkPolyData() for i in range(numberOfOutputPoints): t = (numberOfInputPoints-1.)/(numberOfOutputPoints-1.)*i x, y, z = aSplineX.Evaluate( t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t) points.InsertPoint(i, x, y, z) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(numberOfOutputPoints) for i in range(numberOfOutputPoints): lines.InsertCellPoint(i) profileData.SetPoints(points) profileData.SetLines(lines) actline = Actor(profileData, c=c, alpha=alpha, legend=legend) actline.GetProperty().SetLineWidth(s) actline.GetProperty().SetInterpolationToPhong() return actline