[vtkusers] 3D axis that follows main actor: Python / wxWindows / VTK
Uwe Rempler
rempler at mechbau.uni-stuttgart.de
Wed Feb 4 09:57:57 EST 2004
hi list,
not so long ago i needed to create a 3d axis that automatically orients
itself relative to the actor in the main renderer. i've found a very
helpful snippet in the mailing list archive written in c++:
http://public.kitware.com/pipermail/vtkusers/2001-September/007992.html
because of my other partially finished program i made a translation in
python using AddObserver() instead of the vtkCallbackCommand() which i
was not really able to access within python. in addition to steve boyd's
code i made the overlaying renderer transparent via different layers and
removeable...
because of the nice community here which helped me a lot (and i hope
it'll do this in future too ;-) i would like to share my little piece of
code with you.
hope this example is of assistance to you ;-)
thank you all
greetings
uwe
#!/usr/bin/python
#------------------------------------ +++
--------------------------------------
# Alpha:
# ======
# and now for something completely different...
#
anfang = '- ALPHA ' * 7 + '-'
print
print anfang
print '-' * len(anfang)
print
#------------------------------------ +++
--------------------------------------
#-------------------------------------------------------------------------------
# import modules
import vtk
from wxPython.wx import *
from vtk.wx.wxVTKRenderWindow import *
#-------------------------------------------------------------------------------
# global / static variable
SHOW = 'TRUE'
#-------------------------------------------------------------------------------
# wx-stuff..
[wxID_AXISMAINWINDOW, wxID_AXISMAINWINDOWBTNSHOWAXIS,
wxID_AXISMAINWINDOWPANEL1, wxID_AXISMAINWINDOWBTNQUIT,
] = map(lambda _init_ctrls: wxNewId(), range(4))
#-------------------------------------------------------------------------------
class DisplayAxis:
def __init__(self, app, main):
global SHOW
self.app = app
self.main = main
self.renwin = self.main.widget.GetRenderWindow()
try:
self.main.ren.Render()
if SHOW == 'TRUE':
self._showAxis()
SHOW = 'FALSE'
else:
self._hideAxis()
SHOW = 'TRUE'
except:
print 'no renderwidget...'
def _showAxis(self):
# create / show 3D-axis
self.axisXArrow = vtk.vtkArrowSource()
self.axisYArrow = vtk.vtkArrowSource()
self.axisZArrow = vtk.vtkArrowSource()
self.axisXMapper = vtk.vtkPolyDataMapper()
self.axisXMapper.SetInput(self.axisXArrow.GetOutput())
self.axisXMapper.ScalarVisibilityOff()
self.axisYMapper = vtk.vtkPolyDataMapper()
self.axisYMapper.SetInput(self.axisYArrow.GetOutput())
self.axisYMapper.ScalarVisibilityOff()
self.axisZMapper = vtk.vtkPolyDataMapper()
self.axisZMapper.SetInput(self.axisZArrow.GetOutput())
self.axisZMapper.ScalarVisibilityOff()
self.axisXArrowActor = vtk.vtkActor()
self.axisXArrowActor.SetMapper(self.axisXMapper)
self.axisXArrowActor.GetProperty().SetColor(1, 0, 0) # x-axis >> red
self.axisYArrowActor = vtk.vtkActor()
self.axisYArrowActor.RotateY(-90)
self.axisYArrowActor.GetProperty().SetColor(0, 1, 0) # y-axis >>
green
self.axisYArrowActor.SetMapper(self.axisYMapper)
self.axisZArrowActor = vtk.vtkActor()
self.axisZArrowActor.RotateZ(90)
self.axisZArrowActor.GetProperty().SetColor(0, 0, 1) # z-axis >>
blue
self.axisZArrowActor.SetMapper(self.axisZMapper)
self.axisAssembly = vtk.vtkAssembly()
self.axisAssembly.AddPart(self.axisXArrowActor)
self.axisAssembly.AddPart(self.axisYArrowActor)
self.axisAssembly.AddPart(self.axisZArrowActor)
self.axisAssembly.PickableOff()
self.axisRenderer = vtk.vtkRenderer()
self.axisRenderer.AddActor(self.axisAssembly)
self.axisRenderer.SetViewport(0.8, 0, 1, 0.2)
self.axisRenderer.InteractiveOff()
self.axisRenderer.AddActor(self.axisAssembly)
self.renwin.AddRenderer(self.axisRenderer)
self.renwin.SetNumberOfLayers(2)
self.main.ren.SetLayer(1)
self.axisRenderer.SetLayer(0)
self._updateAxis()
self.renwin.Render()
# add observer to get any changes made to the main renderer
self.main.ren.AddObserver('AnyEvent', self._updateAxis)
def _hideAxis(self):
# hide / remove 3D-axis
self.axisRenderer = self.renwin.GetRenderers()
self.axisRenderer.RemoveItem(1)
self.main.ren.RemoveObserver(0)
self.renwin.Render()
def _updateAxis(self, object = None, event_string = None):
# set the axis camera according to the main renderer
camPos, camFoc, axisFoc = [], [], []
camPos = self.main.ren.GetActiveCamera().GetPosition()
camFoc = self.main.ren.GetActiveCamera().GetFocalPoint()
axisFoc = self.axisRenderer.GetActiveCamera().GetFocalPoint()
self.axisRenderer.GetActiveCamera().SetViewUp(self.main.ren.GetActiveCamera().GetViewUp())
self.axisRenderer.GetActiveCamera().SetPosition(
camPos[0] - camFoc[0] + axisFoc[0],
camPos[1] - camFoc[1] + axisFoc[1],
camPos[2] - camFoc[2] + axisFoc[2])
self.axisRenderer.ResetCamera()
size = self.main.widget.GetSize()
self.axisRenderer.SetViewport(
(float(size[0]) - 120.) / float(size[0]), 0.,
1.,
120. / float(size[1]))
#-------------------------------------------------------------------------------
# mainwindow
class AxisMainWindow(wxFrame):
def _init_ctrls(self, prnt):
wxFrame.__init__(self, id=wxID_AXISMAINWINDOW,
name='AxisMainWindow', parent=prnt, pos=wxPoint(300, 400),
size=wxSize(500, 500), style=wxDEFAULT_FRAME_STYLE,
title='AxisMainWindow')
self.btnShowAxis = wxButton(id=wxID_AXISMAINWINDOWBTNSHOWAXIS,
label='Show Axis', name='btnShowAxis', parent=self,
pos=wxPoint(10, 10), size=wxSize(100, 30), style=0)
EVT_BUTTON(self.btnShowAxis, wxID_AXISMAINWINDOWBTNSHOWAXIS,
self.OnBtnshowAxisButton)
self.btnQuit = wxButton(id=wxID_AXISMAINWINDOWBTNQUIT,
label='Quit', name='btnQuit', parent=self,
pos=wxPoint(390, 10),size=wxSize(100, 30),
style=wxBU_AUTODRAW, validator=wxDefaultValidator)
EVT_BUTTON(self.btnQuit, wxID_AXISMAINWINDOWBTNQUIT,
self.OnBtnquitButton)
self.panel1 = wxPanel(id=wxID_AXISMAINWINDOWPANEL1,
name='panel1', parent=self, pos=wxPoint(10, 50),
size=wxSize(480, 440), style=wxSUNKEN_BORDER)
EVT_SIZE(self.panel1, self.OnAxisMainWindowSize)
def __init__(self, parent, app):
self.app = app
self._init_ctrls(parent)
self.panel1.SetAutoLayout(true)
self.CreateRenderFrame()
self.AxisMainWindowSetSizer()
def AxisMainWindowSetSizer(self):
ButtonBoxTop = wxBoxSizer(wxHORIZONTAL)
ButtonBoxTop.Add(self.btnShowAxis, 0)
ButtonBoxTop.Add(0, 0, 1, 0)
ButtonBoxTop.Add(self.btnQuit, 0, wxALIGN_RIGHT, 0)
PanelBox = wxBoxSizer(wxHORIZONTAL)
PanelBox.Add(self.panel1, 1, wxEXPAND, 0)
BigBox = wxBoxSizer(wxVERTICAL)
BigBox.Add(ButtonBoxTop, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, 10)
BigBox.Add(PanelBox, 1, wxEXPAND | wxALL, 10)
self.SetAutoLayout(true)
self.SetSizer(BigBox)
def CreateRenderFrame(self):
self.widget = wxVTKRenderWindow(self.panel1, -1,
size=self.panel1.GetSizeTuple())
self.ren = vtkRenderer()
self.ren.SetBackground(1, 1, 1)
self.widget.GetRenderWindow().AddRenderer(self.ren)
self.cone = vtkConeSource()
self.cone.SetResolution(8)
self.coneMapper = vtkPolyDataMapper()
self.coneMapper.SetInput(self.cone.GetOutput())
self.coneActor = vtkActor()
self.coneActor.SetMapper(self.coneMapper)
self.ren.AddActor(self.coneActor)
self.widget.Render()
DisplayAxis(self.app, self)
def OnBtnquitButton(self, event):
self.AxisMainWindowQuit()
def OnBtnshowAxisButton(self, event):
DisplayAxis(self.app, self)
def OnAxisMainWindowSize(self, event):
try:
self.size = event.GetSize()
self.widget.SetSize(self.size) # resize renderwindow with
# panel event.size
self.widget.Reset() # reset view
except:
pass
def AxisMainWindowQuit(self):
self.app.AxisQuit()
#-------------------------------------------------------------------------------
# application
class AxisApp(wxApp):
def OnInit(self):
self.main = create(None, self)
self.SetTopWindow(self.main)
self.main.Show();self.main.Hide();self.main.Show()
return True
def AxisQuit(self):
self.ExitMainLoop()
#-------------------------------------------------------------------------------
# create / return mainwindow
def create(parent, app):
return AxisMainWindow(parent, app)
#-------------------------------------------------------------------------------
# start mainloop()
def main():
application = AxisApp(0)
application.MainLoop()
#-------------------------------------------------------------------------------
# on startup call main()
if __name__ == '__main__':
main()
#------------------------------------ +++
--------------------------------------
# Omega:
# ======
# that's all folks...
#
print
ende = '- OMEGA ' * 7 + '-'
print '-' * len(ende)
print ende
print
#------------------------------------ +++
--------------------------------------
More information about the vtkusers
mailing list