""" This module takes a cut plane and warps it using a vtkWarpVector as per the vector times a scale factor. This will work for any dataset. This code is distributed under the conditions of the BSD license. See LICENSE.txt for details. Copyright (c) 2001-2002, Prabhu Ramachandran. """ __author__ = "Prabhu Ramachandran " __version__ = "$Revision: 1.5 $" __date__ = "$Date: 2005/08/02 18:30:14 $" import Base.Objects, Common import Tkinter, tkColorChooser, math import vtk import vtkPipeline.vtkMethodParser debug = Common.debug class WarpVectorCutPlane (Base.Objects.CutPlaneModule): """ This module takes a cut plane and warps it using a vtkWarpVector as per the vector times a scale factor. This will work for any dataset. """ def __init__ (self, mod_m): debug ("In WarpVectorCutPlane::__init__ ()") Common.state.busy () Base.Objects.CutPlaneModule.__init__ (self, mod_m) self.cut = vtk.vtkCutter () self.warp = vtk.vtkWarpVector () self.norm = vtk.vtkPolyDataNormals () self.mapper = self.map = vtk.vtkPolyDataMapper () self.map.SetLookupTable (self.mod_m.get_scalar_lut ()) self.actor = self.act = vtk.vtkActor () self.data_out = self.mod_m.GetOutput () self._initialize () self._gui_init () self.renwin.Render () Common.state.idle () def __del__ (self): debug ("In WarpVectorCutPlane::__del__ ()") if self.act: self.renwin.remove_actors (self.act) self.renwin.Render () def _initialize (self): debug ("In WarpVectorCutPlane::_initialize ()") self.cut.SetInput (self.data_out) self.cut.SetCutFunction (self.plane) self.warp.SetScaleFactor (1.0) self.warp.SetInput (self.cut.GetOutput ()) self.map.SetInput (self.warp.GetOutput ()) self.act.SetMapper (self.map) self.data_range = self.mod_m.get_scalar_data_range () self.map.SetScalarRange (self.data_range) self.act.GetProperty ().BackfaceCullingOff () self.act.GetProperty ().FrontfaceCullingOff () self.center = self.data_out.GetCenter () self.plane.SetOrigin (self.center) self.plane.SetNormal (0.0, 0.0, 1.0) self.set_def_step_size () self.slider_pos = 0 self.renwin.add_actors (self.act) # used for the pipeline browser self.pipe_objs = self.act def set_def_step_size (self): out = self.data_out bnd = out.GetBounds () n = out.GetNumberOfCells () if not n: n = out.GetNumberOfPoints () data_2d = 0 vol = 1.0 for i in range (0,3): l = abs (bnd[2*i+1] - bnd[2*i]) if l == 0.0: data_2d=1 else: vol = vol*l l = vol/n if data_2d == 1: self.step_size = math.sqrt (l) else: self.step_size = math.pow (l, 1.0/3.0) def _gui_init (self): debug ("In WarpVectorCutPlane::_gui_init ()") self.step_var.set (self.step_size) self.n_step_var.set (10) self._auto_sweep_init () self.sweep_step.set (1) self.normals_on = Tkinter.IntVar () self.normals_on.set (0) self.angle_var = Tkinter.DoubleVar () self.angle_var.set (45) def SetInput (self, source): debug ("In WarpVectorCutPlane::SetInput ()") Common.state.busy () self.data_out = source self.cut.SetInput (self.data_out) dr = self.mod_m.get_scalar_data_range () if (dr[0] != self.data_range[0]) or (dr[1] != self.data_range[1]): self.data_range = dr self.map.SetScalarRange (dr) Common.state.idle () def save_config (self, file): debug ("In WarpVectorCutPlane::save_config ()") file.write ("%d, %d, %f, %d, %f\n"%(self.slider_pos, self.n_step_var.get (), self.step_size, self.normals_on.get (), self.angle_var.get ())) p = vtkPipeline.vtkMethodParser.VtkPickler () for obj in (self.plane, self.cut, self.warp, self.map, self.act, self.act.GetProperty ()): p.dump (obj, file) def load_config (self, file): debug ("In WarpVectorCutPlane::load_config ()") self.slider_pos, n_s, self.step_size, \ nor, ang = eval (file.readline ()) self.n_step_var.set (n_s) self.normals_on.set (nor) self.angle_var.set (ang) p = vtkPipeline.vtkMethodParser.VtkPickler () for obj in (self.plane, self.cut, self.warp, self.map, self.act, self.act.GetProperty ()): p.load (obj, file) self.do_normals () def config_changed (self): debug ("In WarpVectorCutPlane::config_changed ()") pass def make_main_gui (self): debug ("In WarpVectorCutPlane::make_main_gui ()") self.make_cut_plane_gui () self.make_my_gui () self.make_actor_gui (compact=1) self.make_auto_sweep_gui () def _get_ranges (self, val): debug ("In WarpVectorCutPlane::_get_ranges ()") if val == 0.0: res, min_v, max_v = 0.1, -1.0, 1.0 elif val > 0: res = val/10.0 min_v = val - 50*res max_v = val + 50*res #min_v = max (0, min_v) else: res = abs (val)/10.0 min_v = val - 50*res max_v = val + 50*res #max_v = min (0, max_v) return res, min_v, max_v def make_my_gui (self): debug ("In WarpVectorCutPlane::make_my_gui()") frame = Tkinter.Frame (self.root, relief='ridge', bd=2) frame.pack (side='top', fill='both', expand=1) self.make_warp_gui (frame) self.make_normals_gui (frame) def make_normals_gui (self, master): debug ("In WarpVectorCutPlane::make_normals_gui ()") frame = Tkinter.Frame (master, relief='ridge', bd=2) frame.pack (side='top', fill='both', expand=1) rw = 0 norm = Tkinter.Checkbutton (frame, text="PolyDataNormals", variable=self.normals_on, onvalue=1, offvalue=0, command=self.do_normals) norm.grid (row=rw, columnspan=1, sticky='w') #rw = rw + 1 lab = Tkinter.Label (frame, text="Angle: ") lab.grid (row=rw, column=1, sticky='w') entry = Tkinter.Entry (frame, width=10, relief='sunken', textvariable=self.angle_var) entry.grid (row=rw, column=2, sticky='ew') entry.bind ("", self.do_normals) def make_warp_gui (self, master): debug ("In WarpVectorCutPlane::make_warp_gui ()") frame = Tkinter.Frame (master, relief='ridge', bd=2) frame.pack (side='top', fill='both', expand=1) cur_scale = self.warp.GetScaleFactor () res, min_v, max_v = self._get_ranges (cur_scale) self.scale_res_var = Tkinter.DoubleVar () self.scale_res_var.set (res) self.min_scale_var = Tkinter.DoubleVar () self.min_scale_var.set (min_v) self.max_scale_var = Tkinter.DoubleVar () self.max_scale_var.set (max_v) rw = 0 sl = Tkinter.Scale (frame, label="Set Scale Factor", from_= self.min_scale_var.get (), to = self.max_scale_var.get (), length="5c", orient='horizontal', resolution=self.scale_res_var.get ()) sl.set (cur_scale) sl.grid (row=rw, column=0, columnspan=3, sticky='ew') rw = rw + 1 sl.bind ("", self.change_scale) self.scale_slider = sl lab = Tkinter.Label (frame, text="Scale slider: Min, Max, Resolution") lab.grid (row=rw, column=0, columnspan=3, sticky='w') rw = rw+1 # min entry = Tkinter.Entry (frame, width=10, relief='sunken', textvariable=self.min_scale_var) entry.grid (row=rw, column=0, sticky='we') entry.bind ("", self.change_scale_limits) # max entry = Tkinter.Entry (frame, width=10, relief='sunken', textvariable=self.max_scale_var) entry.grid (row=rw, column=1, sticky='we') entry.bind ("", self.change_scale_limits) # resolution entr = Tkinter.Entry (frame, width=10, relief='sunken', textvariable=self.scale_res_var) entr.grid (row=rw, column=2, sticky='ew') entr.bind ("", self.set_scale_resolution) def set_scale_resolution (self, event=None): """ Called when the scale slider resolution is changed. """ debug ("In WarpVectorCutPlane::set_scale_resolution()") self.scale_slider.config (resolution=self.scale_res_var.get ()) def change_scale (self, event=None): debug ("In WarpVectorCutPlane::change_scale()") Common.state.busy () self.warp.SetScaleFactor (self.scale_slider.get()) self.mod_m.Update () Common.state.idle () def change_scale_limits (self, event=None): debug ("In WarpVectorCutPlane::change_scale_limits()") self.scale_slider.config (from_ = self.min_scale_var.get(), to = self.max_scale_var.get()) def do_normals (self, event=None): debug ("In WarpVectorCutPlane::do_normals ()") Common.state.busy () if self.normals_on.get (): self.norm.SetInput (self.warp.GetOutput ()) self.norm.SetFeatureAngle (self.angle_var.get ()) self.map.SetInput (self.norm.GetOutput ()) else: self.map.SetInput (self.warp.GetOutput ()) self.renwin.Render () Common.state.idle () def do_sweep (self, event=None): debug ("In WarpVectorCutPlane::do_sweep ()") if self.sweep_var.get (): val = int (1000*self.sweep_delay.get ()) self.root.after (val, self.update_sweep) def update_sweep (self): debug ("In WarpVectorCutPlane::update_sweep ()") if self.sweep_var.get (): d_pos = self.sweep_step.get () pos = self.slider_pos + d_pos if (d_pos > 0) and (pos > self.n_step_var.get ()): pos = -self.n_step_var.get () elif (d_pos < 0) and (pos < -self.n_step_var.get ()): pos = self.n_step_var.get () self.slider[2].set (pos) self.change_slider () val = int (1000*self.sweep_delay.get ()) self.root.after (val, self.update_sweep)