def meshBody(fileName, scale=(1., 1., 1.)): """ Return a mesh actor and the appropriate static transform. """ reader = FILE_READER[splitext(fileName)[1]](file_name=fileName) output = reader.output # if a scale is set we have to apply it if map(float, scale) != [1., 1., 1.]: tpdf_transform = tvtk.Transform() tpdf_transform.identity() tpdf_transform.scale(scale) tpdf = tvtk.TransformPolyDataFilter(input=reader.output, transform=tpdf_transform) tpdf.update() output = tpdf.output # compute mesh normal to have a better render and reverse mesh normal # if the scale flip them pdn = tvtk.PolyDataNormals(input=output) pdn.update() output = pdn.output pdm = tvtk.PolyDataMapper(input=output) actor = tvtk.Actor(mapper=pdm) actor.user_transform = tvtk.Transform() return actor, sva.PTransformd.Identity()
def __init__(self, X=sva.PTransformd.Identity(), length=0.1, text=''): """ Create a 3D axis. """ self._X = X self.axesActor = tvtk.AxesActor(total_length=(length, ) * 3, axis_labels=False) self.axesActor.user_transform = tvtk.Transform() textSource = tvtk.TextSource(text=text, backing=False) # textPdm = tvtk.PolyDataMapper(input=textSource.output) textPdm = tvtk.PolyDataMapper() # https://stackoverflow.com/questions/35089379/how-to-fix-traiterror-the-input-trait-of-a-instance-is-read-only # configure_input_data(textPdm, textSource.output_port) # https://github.com/enthought/mayavi/issues/521 textPdm.input_connection = textSource.output_port #self.textActor = tvtk.Actor(mapper=textPdm) self.textActor = tvtk.Follower(mapper=textPdm) # take the maximum component of the bound and use it to scale it m = max(self.textActor.bounds) scale = length / m self.textActor.scale = (scale, ) * 3 # TODO compute the origin well... self.textActor.origin = ( -(self.textActor.bounds[0] + self.textActor.bounds[1]) / 2., -(self.textActor.bounds[2] + self.textActor.bounds[3]) / 2., -(self.textActor.bounds[4] + self.textActor.bounds[5]) / 2., ) ySize = self.textActor.bounds[3] * 1.2 self.X_text = sva.PTransformd(e.Vector3d(0., -ySize, 0.)) self._transform()
def _pipeline_default(self): grid = self.vtk_grid grid.set_execute_method(self.create_grid) grid.modified() trans = tvtk.Transform() trans.rotate_x(90.) cyl = self.vtk_cylinder cyl.transform = trans clip1 = tvtk.ClipVolume(input=grid.structured_points_output, clip_function=self.vtk_cylinder, inside_out=1) clip2 = tvtk.ClipDataSet(input=clip1.output, clip_function=self.vtk_quadric, inside_out=1) topoly = tvtk.GeometryFilter(input=clip2.output) norms = tvtk.PolyDataNormals(input=topoly.output) transF = tvtk.TransformFilter(input=norms.output, transform=self.transform) self.config_pipeline() #clip1.update() grid.modified() return transF
def _pipeline_default(self): sqrt2 = numpy.sqrt(2) x = -sqrt2 * numpy.cos(numpy.pi * 2. / 3) y = sqrt2 * numpy.sin(numpy.pi * 2. / 3) p1 = tvtk.PlaneSource(origin=(0,0,0), \ point1=(-sqrt2,0,1), point2=(x,y,1)) p2 = tvtk.PlaneSource(origin=(0,0,0), \ point1=(x,y,1), point2=(x,-y,1)) p3 = tvtk.PlaneSource(origin=(0,0,0), \ point1=(x,-y,1), point2=(-sqrt2,0,1)) for p in (p1, p2, p3): p.set_resolution(32, 32) append = tvtk.AppendPolyData() append.add_input_connection(p1.output_port) append.add_input_connection(p2.output_port) append.add_input_connection(p3.output_port) scale_f = tvtk.TransformFilter(input_connection=append.output_port, transform=self.scale) trans = tvtk.Transform() trans.rotate_x(90.0) self.imp_cyl.transform = trans clip = tvtk.ClipPolyData(input_connection=scale_f.output_port, clip_function=self.imp_cyl, inside_out=True) transF2 = tvtk.TransformFilter(input_connection=clip.output_port, transform=self.transform) self.config_pipeline() return transF2
def __set_pure_state__(self, state): # Pop the transformation matrix for the box widget. mat = state.pop('matrix') # Now set their state. set_state(self, state, first=['widget_mode'], ignore=['*']) # Set state of rest of the attributes ignoring the widget_mode. set_state(self, state, ignore=['widget_mode']) # Set the transformation for Box widget. tfm = tvtk.Transform() tfm.set_matrix(pickle.loads(mat)) w = self._widget_dict['Box'] w.set_transform(tfm) # Some widgets need some cajoling to get their setup right. w = self.widget # Set the input. if len(self.inputs) > 0: self.configure_input(w, self.inputs[0].outputs[0]) w.update_traits() mode = self.widget_mode if mode == 'Plane': wd = state._widget_dict[mode] w.origin = wd.origin w.normal = wd.normal w.update_placement() self.update_implicit_function() # Set the widgets trait so that the widget is rendered if needed. self.widgets = [w]
def __init__(self, linear, angular, frame, linColor, angColor): """ Create the visualization of a 6D vector with a linear and angular part. Parameter: linear: 3d linear component (e.Vector3d) angular: 3d angular component (e.Vector3d) frame: vector frame (sva.PTransformd) linColor: linear component color (float, float, float) angColor: angular component color (float, float, float) """ self.linearActor, X_l = self._createVector(linear, frame, linColor) self.angularActor, X_a = self._createVector(angular, frame, angColor) # create a Arc around the angular axis # The arc must turn around the X axis (Arrow default axis) angNorm = angular.norm() angNormW = angNorm*0.3 arcSource = tvtk.ArcSource(point1=(angNorm/2., -angNormW, -angNormW), point2=(angNorm/2., -angNormW, angNormW), center=(angNorm/2., 0., 0.), negative=True, resolution=20) arcPdm = tvtk.PolyDataMapper(input=arcSource.output) self.arcActor = tvtk.Actor(mapper=arcPdm) self.arcActor.property.color = angColor self.arcActor.user_transform = tvtk.Transform() # apply the angular transform setActorTransform(self.arcActor, X_a)
def endEffectorBody(X_s, size, color): """ Return a end effector reprsented by a plane and the appropriate static transform. """ apd = tvtk.AppendPolyData() ls = tvtk.LineSource(point1=(0., 0., 0.), point2=tuple(X_s.translation())) p1 = (sva.PTransformd(e.Vector3d.UnitX() * size) * X_s).translation() p2 = (sva.PTransformd(e.Vector3d.UnitY() * size) * X_s).translation() ps = tvtk.PlaneSource(origin=tuple(X_s.translation()), point1=tuple(p1), point2=tuple(p2), center=tuple(X_s.translation())) apd.add_input(ls.output) apd.add_input(ps.output) pdm = tvtk.PolyDataMapper(input=apd.output) actor = tvtk.Actor(mapper=pdm) actor.property.color = color actor.user_transform = tvtk.Transform() return actor, sva.PTransformd.Identity()
def __init__(self, X=sva.PTransformd.Identity(), length=0.1, text=''): """ Create a 3D axis. """ self._X = X self.axesActor = tvtk.AxesActor(total_length=(length, ) * 3, axis_labels=False) self.axesActor.user_transform = tvtk.Transform() textSource = tvtk.TextSource(text=text, backing=False) textPdm = tvtk.PolyDataMapper(input=textSource.output) #self.textActor = tvtk.Actor(mapper=textPdm) self.textActor = tvtk.Follower(mapper=textPdm) # take the maximum component of the bound and use it to scale it m = max(self.textActor.bounds) scale = length / m self.textActor.scale = (scale, ) * 3 # TODO compute the origin well... self.textActor.origin = ( -(self.textActor.bounds[0] + self.textActor.bounds[1]) / 2., -(self.textActor.bounds[2] + self.textActor.bounds[3]) / 2., -(self.textActor.bounds[4] + self.textActor.bounds[5]) / 2., ) ySize = self.textActor.bounds[3] * 1.2 self.X_text = sva.PTransformd(e.Vector3d(0., -ySize, 0.)) self._transform()
def _pipeline_default(self): grid = self.vtk_grid #grid.set_execute_method(self.create_grid) grid.modified() trans = tvtk.Transform() trans.rotate_x(90.) cyl = self.vtk_cylinder cyl.transform = trans clip1 = tvtk.ClipVolume(input_connection=grid.output_port, clip_function=self.vtk_cylinder, inside_out=1) self.clip2.set(input_connection=clip1.output_port, clip_function=self.vtk_sphere, inside_out=1) topoly = tvtk.GeometryFilter(input_connection=self.clip2.output_port) norms = tvtk.PolyDataNormals(input_connection=topoly.output_port) transF = tvtk.TransformFilter(input_connection=norms.output_port, transform=self.transform) self.config_pipeline() grid.modified() return transF
def linesBody(mb, bodyName, successorJointsName): """ Return a mesh represented by lines and the appropriate static transform. """ apd = tvtk.AppendPolyData() sources = [] # create a line from the body base to the next joint for s in map(mb.jointIndexByName, successorJointsName[bodyName]): X_s = mb.transform(s) sources.append(tvtk.LineSource(point1=(0., 0., 0.), point2=tuple(X_s.translation()))) # add an empty source to avoid a warning if AppendPolyData have 0 source if len(sources) == 0: sources.append(tvtk.PointSource(radius=0.)) map(lambda s: apd.add_input(s.output), sources) apd.update() pdm = tvtk.PolyDataMapper() pdm.input_connection = apd.output_port actor = tvtk.Actor(mapper=pdm) actor.property.color = (0., 0., 0.) actor.user_transform = tvtk.Transform() return actor, sva.PTransformd.Identity()
def _oct_glyph(glyph_source, transform): from tvtk.api import tvtk from tvtk.common import configure_input from traits.api import Array gs = tvtk.PlatonicSolidSource() # Workaround for: # File "mayavi/components/glyph_source.py", line 231, in _glyph_position_changed # noqa: E501 # g.center = 0.0, 0.0, 0.0 # traits.trait_errors.TraitError: Cannot set the undefined 'center' attribute of a 'TransformPolyDataFilter' object. # noqa: E501 class SafeTransformPolyDataFilter(tvtk.TransformPolyDataFilter): center = Array(shape=(3,), value=np.zeros(3)) gs.solid_type = 'octahedron' if transform is not None: # glyph: mayavi.modules.vectors.Vectors # glyph.glyph: vtkGlyph3D # glyph.glyph.glyph: mayavi.components.glyph.Glyph assert transform.shape == (4, 4) tr = tvtk.Transform() tr.set_matrix(transform.ravel()) trp = SafeTransformPolyDataFilter() configure_input(trp, gs) trp.transform = tr trp.update() gs = trp glyph_source.glyph_source = gs
def make_tube(height, radius, resolution, rx=0, ry=0, rz=0): cs1 = tvtk.CylinderSource(height=height, radius=radius[0], resolution=resolution) cs2 = tvtk.CylinderSource(height=height + 0.1, radius=radius[1], resolution=resolution) triangle1 = tvtk.TriangleFilter(input_connection=cs1.output_port) triangle2 = tvtk.TriangleFilter(input_connection=cs2.output_port) tr = tvtk.Transform() tr.rotate_x(rx) tr.rotate_y(ry) tr.rotate_z(rz) tf1 = tvtk.TransformFilter(transform=tr, input_connection=triangle1.output_port) tf2 = tvtk.TransformFilter(transform=tr, input_connection=triangle2.output_port) bf = tvtk.BooleanOperationPolyDataFilter() bf.operation = "difference" bf.set_input_connection(0, tf1.output_port) bf.set_input_connection(1, tf2.output_port) m = tvtk.PolyDataMapper(input_connection=bf.output_port, scalar_visibility=False) a = tvtk.Actor(mapper=m) return bf, a, tf1, tf2
def _get_x_axis(self): temp = tvtk.Transform() o,e = self._orientation temp.rotate_z(o) temp.rotate_x(e) temp.rotate_z(self.rotation) direct = temp.transform_point(1,0,0) return direct
def makeActor(source, color): """ Create an actor from a source and a color. """ pdm = tvtk.PolyDataMapper(input=source.output) actor = tvtk.Actor(mapper=pdm) actor.property.color = color actor.user_transform = tvtk.Transform() return actor
def _get_direction(self): temp = tvtk.Transform() o,e = self._orientation temp.rotate_z(o) temp.rotate_x(e) temp.rotate_z(self.rotation) direct = temp.transform_point(0,0,1) #print "get direction", direct, o, e return direct
def _pipeline_default(self): cyl = self.cyl cyl.resolution = 63 #use a prime no to avoid vertex degeneracy # Important to ensure the cylinder end doesn't coincide with the corner of the cube cyl.height = self.thickness - 1 cyl.radius = self.diameter / 2.0 cyl.center = (0, (self.thickness / 2) - 1, 0) print("thickness", self.thickness) print("diameter", self.diameter) size = max(self.thickness, self.diameter) * 2 cube = self.cube cube.set_bounds(0, size, 0, size, 0, size) tf = tvtk.Transform() tf.post_multiply() tf.rotate_x(-45.0) tf.rotate_wxyz(35.26438968275, 0, 0, 1) tfilt = tvtk.TransformFilter(input_connection=cube.output_port) tfilt.transform = tf tri1 = tvtk.TriangleFilter(input_connection=cyl.output_port) tri2 = tvtk.TriangleFilter(input_connection=tfilt.output_port) tri1.update() tri2.update() intersect = tvtk.BooleanOperationPolyDataFilter() intersect.operation = "intersection" intersect.add_input_connection(0, tri1.output_port) intersect.add_input_connection(1, tri2.output_port) intersect.tolerance = 1e-8 tf2 = tvtk.Transform() tf2.rotate_x(90.0) tf2.rotate_y(60.0) orient = tvtk.TransformFilter(input_connection=intersect.output_port, transform=tf2) norm = tvtk.PolyDataNormals(input_connection=orient.output_port) transF = tvtk.TransformFilter(input_connection=norm.output_port, transform=self.transform) self.config_pipeline() return transF
def __get_pure_state__(self): d = super(ImplicitWidgets, self).__get_pure_state__() for attr in ('_first', '_busy', '_observer_id', 'widget', 'implicit_function'): d.pop(attr, None) # The box widget requires a transformation matrix to be pickled. tfm = tvtk.Transform() w = self._widget_dict['Box'] w.get_transform(tfm) d['matrix'] = pickle.dumps(tfm.matrix) return d
def _createVector(self, vector, frame, color): source = tvtk.ArrowSource() pdm = tvtk.PolyDataMapper(input=source.output) actor = tvtk.Actor(mapper=pdm) actor.user_transform = tvtk.Transform() actor.property.color = color norm = vector.norm() actor.scale = (norm,)*3 quat = e.Quaterniond() # arrow are define on X axis quat.setFromTwoVectors(vector, e.Vector3d.UnitX()) X = sva.PTransformd(quat)*frame setActorTransform(actor, X) return actor, X
def setup_pipeline(self): """Override this method so that it *creates* the tvtk pipeline. This method is invoked when the object is initialized via `__init__`. Note that at the time this method is called, the tvtk data pipeline will *not* yet be setup. So upstream data will not be available. The idea is that you simply create the basic objects and setup those parts of the pipeline not dependent on upstream sources and filters. You should also set the `actors` attribute up at this point. """ self._trfm.transform = tvtk.Transform() # Setup the glyphs. self.glyph_source = self.glyph_dict['glyph_source2d']
def _pipeline_default(self): grid = self.vtk_grid #grid.set_execute_method(self.create_grid) grid.modified() trans = tvtk.Transform() trans.rotate_x(90.) cyl = self.vtk_cylinder cyl.transform = trans clip1 = tvtk.ClipVolume(input_connection=grid.output_port, clip_function=self.vtk_cylinder, inside_out=1) self.clip2.set(input_connection=clip1.output_port, clip_function=self.vtk_sphere1, inside_out=1) self.clip3.set(input_connection=self.clip2.output_port, clip_function=self.vtk_sphere3, inside_out=1) clip4 = tvtk.ClipDataSet(input_connection=self.clip3.output_port, clip_function=self.vtk_sphere2, inside_out=1) clip5 = tvtk.ClipDataSet(input_connection=self.clip3.output_port, clip_function=self.vtk_sphere2, inside_out=0) topoly = tvtk.GeometryFilter(input_connection=clip4.output_port) topoly2 = tvtk.GeometryFilter(input_connection=clip5.output_port) append = tvtk.AppendPolyData() append.add_input_connection(topoly.output_port) append.add_input_connection(topoly2.output_port) norms = tvtk.PolyDataNormals(input_connection=append.output_port) transF = tvtk.TransformFilter(input_connection=norms.output_port, transform=self.transform) self.on_geometry_changed() self.config_pipeline() grid.modified() return transF
def _createVector(self, vector, frame, color): source = tvtk.ArrowSource() # pdm = tvtk.PolyDataMapper(input=source.output) pdm = tvtk.PolyDataMapper() # https://github.com/enthought/mayavi/issues/521 pdm.input_connection = source.output_port # configure_input_data(pdm, source) prop = tvtk.Property(color=color) actor = tvtk.Actor(mapper=pdm, property=prop) actor.user_transform = tvtk.Transform() # commented due to api change, new lines are above Actor creation # actor.property.color = color norm = vector.norm() actor.scale = (norm, ) * 3 quat = e.Quaterniond() # arrow are define on X axis quat.setFromTwoVectors(vector, e.Vector3d.UnitX()) X = sva.PTransformd(quat) * frame transform.setActorTransform(actor, X) return actor, X
def __init__(self, linear, angular, frame, linColor, angColor): """ Create the visualization of a 6D vector with a linear and angular part. Parameter: linear: 3d linear component (e.Vector3d) angular: 3d angular component (e.Vector3d) frame: vector frame (sva.PTransformd) linColor: linear component color (float, float, float) angColor: angular component color (float, float, float) """ self.linearActor, X_l = self._createVector(linear, frame, linColor) self.angularActor, X_a = self._createVector(angular, frame, angColor) # create a Arc around the angular axis # The arc must turn around the X axis (Arrow default axis) angNorm = angular.norm() angNormW = angNorm * 0.3 arcSource = tvtk.ArcSource(point1=(angNorm / 2., -angNormW, -angNormW), point2=(angNorm / 2., -angNormW, angNormW), center=(angNorm / 2., 0., 0.), negative=True, resolution=20) # arcPdm = tvtk.PolyDataMapper(input=arcSource.output) arcPdm = tvtk.PolyDataMapper() # https://stackoverflow.com/questions/35089379/how-to-fix-traiterror-the-input-trait-of-a-instance-is-read-only # configure_input_data(textPdm, textSource)# https://github.com/enthought/mayavi/issues/521 arcPdm.input_connection = arcSource.output_port prop = tvtk.Property(color=angColor) # https://github.com/enthought/mayavi/issues/521 # arcPdm.input_connection = arcSource.output_port self.arcActor = tvtk.Actor(mapper=arcPdm, property=prop) # commented due to api change, new lines are above Actor creation # self.arcActor.property.color = angColor # https://github.com/enthought/mayavi/blob/5c2694b72b329b8d5c469bc459a211378e2c8581/tvtk/pyface/actors.py#L112 self.arcActor.user_transform = tvtk.Transform() # apply the angular transform transform.setActorTransform(self.arcActor, X_a)
def endEffectorBody(X_s, size, color): """ Return a end effector reprsented by a plane and the appropriate static transform. """ apd = tvtk.AppendPolyData() ls = tvtk.LineSource(point1=(0., 0., 0.), point2=tuple(X_s.translation())) p1 = (sva.PTransformd(e.Vector3d.UnitX()*size)*X_s).translation() p2 = (sva.PTransformd(e.Vector3d.UnitY()*size)*X_s).translation() ps = tvtk.PlaneSource(origin=tuple(X_s.translation()), point1=tuple(p1), point2=tuple(p2), center=tuple(X_s.translation())) # apd.add_input(ls.output) # apd.add_input(ps.output) # https://github.com/enthought/mayavi/blob/ac5c8e316335078c25461a0bce4a724ae86f1836/tvtk/tests/test_tvtk.py#L586 apd.add_input_data(ls.output) apd.add_input_data(ps.output) # pdm = tvtk.PolyDataMapper(input=apd.output) # arcPdm = tvtk.PolyDataMapper(input=arcSource.output) pdm = tvtk.PolyDataMapper() # https://stackoverflow.com/questions/35089379/how-to-fix-traiterror-the-input-trait-of-a-instance-is-read-only # configure_input_data(textPdm, textSource)# https://github.com/enthought/mayavi/issues/521 pdm.input_connection = apd.output_port prop = tvtk.Property(color=color) # https://github.com/enthought/mayavi/issues/521 # arcPdm.input_connection = arcSource.output_port actor = tvtk.Actor(mapper=pdm, property=prop) actor.property.color = color actor.user_transform = tvtk.Transform() return actor, sva.PTransformd.Identity()
def transform(self, translate=None, scale=None, rotate=None): """Applies an affine transformation to the current object. Keyword arguments are self explanatory. They can be a tuple or list representing the three-dimensional vector or a single number to use for each of the three components. """ transform = self.actor.user_transform or tvtk.Transform() if translate is not None: transform.translate(self._to_tuple(translate)) if scale is not None: transform.scale(self._to_tuple(scale)) if rotate is not None: rotate = self._to_tuple(rotate) transform.rotate_x(rotate[0]) transform.rotate_y(rotate[1]) transform.rotate_z(rotate[2]) self.actor.user_transform = transform
def transform_pts(centre, direction, points): #take a point from the global referance frame and transform it into the #local referance frame of an object. accepts the x,y,z of the centre and #direction of the object's frame. temp = tvtk.Transform() temp.identity() temp.translate(centre) x, y, z = normaliseVector(direction) Theta = numpy.arccos(z) theta = 180 * Theta / numpy.pi phi = 180 * numpy.arctan2(x, y) / numpy.pi orientation = -phi, -theta temp.rotate_z(-phi) temp.rotate_x(-theta) inv_t = temp.linear_inverse result = transformPoints(inv_t, points) return result
def __init__(self): self.el = 0.0 self.az = 0.0 # Create an arrow. arrow = tvtk.ArrowSource() # Transform it suitably so it is oriented correctly. t = tvtk.Transform() tf = tvtk.TransformFilter() tf.transform = t t.rotate_y(90.0) t.translate((-2, 0, 0)) configure_input_data(tf, arrow.output) mapper = tvtk.PolyDataMapper() configure_input(mapper, tf) self.actor = actor = tvtk.Follower() actor.mapper = mapper prop = actor.property prop.color = 0, 1, 1 prop.ambient = 0.5 prop.diffuse = 0.5
def anim(): x = 0.2 y = 0.3 z = 0.4 cb1 = sch.Box(x, y, z) cb2 = sch.Box(x, y, z) pair = sch.CD_Pair(cb1, cb2) b1s = tvtk.CubeSource(x_length=x, y_length=y, z_length=z) b2s = tvtk.CubeSource(x_length=x, y_length=y, z_length=z) b1m = tvtk.PolyDataMapper(input=b1s.output) b2m = tvtk.PolyDataMapper(input=b2s.output) b1a = tvtk.Actor(mapper=b1m) b2a = tvtk.Actor(mapper=b2m) line = tvtk.LineSource() lineM = tvtk.PolyDataMapper(input=line.output) lineA = tvtk.Actor(mapper=lineM) b1a.user_transform = tvtk.Transform() b2a.user_transform = tvtk.Transform() b1T = sva.PTransformd.Identity() b2T = sva.PTransformd(Vector3d.UnitZ()*2.) setTransform(b1a, b1T) setTransform(b2a, b2T) viewer = mlab.gcf() viewer.scene.add_actors([b1a, b2a, lineA]) rx = ry = rz = 0. t = 0 while True: b1T = sva.PTransformd(sva.RotZ(rz)*sva.RotY(ry)*sva.RotX(rx)) b2T = sva.PTransformd(Vector3d(0., 0., 2. + np.sin(t))) setTransform(b1a, b1T) setTransform(b2a, b2T) cb1.transform(b1T) cb2.transform(b2T) p1 = Vector3d() p2 = Vector3d() pair.distance(p1, p2) line.point1 = list(p1) line.point2 = list(p2) rx += 0.01 ry += 0.005 rz += 0.002 t += 0.05 viewer.scene.render() yield
def callback(widget, event): """This callback sets the transformation of the cone using that setup by the the box.""" t = tvtk.Transform() bw.get_transform(t) bw.prop3d.user_transform = t
def setup_pipeline(self): self.widget = ImplicitWidgets() self._transform = tvtk.Transform() self.filter = tvtk.ClipDataSet() self.widget.on_trait_change(self._handle_widget, 'widget') super(DataSetClipper, self).setup_pipeline()
def setup_pipeline(self): self._transform = tvtk.Transform() self.widget = tvtk.BoxWidget(place_factor=1.1) self.filter = tvtk.TransformFilter() super(TransformData, self).setup_pipeline()