package vtk; import java.awt.Canvas; import java.awt.Graphics; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import javax.swing.SwingUtilities; /** * Java AWT component that encapsulate vtkRenderWindow, vtkRenderer, vtkCamera, * vtkLight. * * If a vtkInteractor is needed, use vtkCanvas instead. This is necessary when * Widget and Picker are used. * * @author Kitware */ public class vtkPanel extends Canvas implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener { private static final long serialVersionUID = 1L; protected vtkRenderWindow rw = new vtkRenderWindow(); protected vtkRenderer ren = new vtkRenderer(); protected vtkCamera cam = null; protected vtkLight lgt = new vtkLight(); protected int lastX; protected int lastY; protected int windowset = 0; protected int lightingset = 0; protected int LightFollowCamera = 1; protected int InteractionMode = 1; protected boolean rendering = false; static { vtkJavaDep.load(); } // Allow access to display lock() and unlock(). // Call these whenever you call something that causes // a Render(). // e.g. // panel.lock(); // // Code that causes a render // panel.unlock(); public void lock() { Lock(); } public void unlock() { UnLock(); } public void Delete() { if(rendering) { return; } rendering = true; // We prevent any further rendering if (this.getParent() != null) { this.getParent().remove(this); } // Free internal VTK objects ren = null; cam = null; lgt = null; // On linux we prefer to have a memory leak instead of a crash if(!rw.GetClassName().equals("vtkXOpenGLRenderWindow")) { rw = null; } else { System.out.println("The renderwindow has been kept around to prevent a crash"); } } protected native int RenderCreate(vtkRenderWindow id0); protected native int Lock(); protected native int UnLock(); public vtkPanel() { rw.AddRenderer(ren); addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); addKeyListener(this); super.setSize(200, 200); rw.SetSize(200, 200); } public vtkPanel(vtkRenderWindow renwin) { rw = renwin; rw.AddRenderer(ren); addMouseListener(this); addMouseMotionListener(this); addKeyListener(this); super.setSize(200, 200); rw.SetSize(200, 200); } public void Report() { // must be performed on awt event thread Runnable updateAComponent = new Runnable() { public void run() { Lock(); System.out.println("direct rendering = " + (rw.IsDirect() == 1)); System.out.println("opengl supported = " + (rw.SupportsOpenGL() == 1)); System.out.println("report = " + rw.ReportCapabilities()); UnLock(); } }; SwingUtilities.invokeLater(updateAComponent); } public vtkRenderer GetRenderer() { return ren; } public vtkRenderWindow GetRenderWindow() { return rw; } public void setSize(int x, int y) { super.setSize(x, y); if (windowset == 1) { Lock(); rw.SetSize(x, y); UnLock(); } } public void addNotify() { super.addNotify(); windowset = 0; rw.SetForceMakeCurrent(); rendering = false; } public void removeNotify() { rendering = true; super.removeNotify(); } public synchronized void Render() { if (!rendering) { rendering = true; if (ren.VisibleActorCount() == 0) { rendering = false; return; } if (rw != null) { if (windowset == 0) { // set the window id and the active camera cam = ren.GetActiveCamera(); if (lightingset == 0) { ren.AddLight(lgt); lgt.SetPosition(cam.GetPosition()); lgt.SetFocalPoint(cam.GetFocalPoint()); lightingset = 1; } RenderCreate(rw); Lock(); rw.SetSize(getWidth(), getHeight()); UnLock(); windowset = 1; this.setSize(getWidth(), getHeight()); } Lock(); rw.Render(); UnLock(); rendering = false; } } } public boolean isWindowSet() { return (this.windowset == 1); } public void paint(Graphics g) { this.Render(); } public void update(Graphics g) { paint(g); } public void LightFollowCameraOn() { this.LightFollowCamera = 1; } public void LightFollowCameraOff() { this.LightFollowCamera = 0; } public void InteractionModeRotate() { this.InteractionMode = 1; } public void InteractionModeTranslate() { this.InteractionMode = 2; } public void InteractionModeZoom() { this.InteractionMode = 3; } public void UpdateLight() { lgt.SetPosition(cam.GetPosition()); lgt.SetFocalPoint(cam.GetFocalPoint()); } public void resetCameraClippingRange() { Lock(); ren.ResetCameraClippingRange(); UnLock(); } public void resetCamera() { Lock(); ren.ResetCamera(); UnLock(); } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (ren.VisibleActorCount() == 0) return; rw.SetDesiredUpdateRate(5.0); lastX = e.getX(); lastY = e.getY(); if ((e.getModifiers() == InputEvent.BUTTON2_MASK) || (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK))) { InteractionModeTranslate(); } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) { InteractionModeZoom(); } else { InteractionModeRotate(); } } public void mouseReleased(MouseEvent e) { rw.SetDesiredUpdateRate(0.01); } public void mouseEntered(MouseEvent e) { this.requestFocus(); } public void mouseExited(MouseEvent e) { } public void mouseMoved(MouseEvent e) { lastX = e.getX(); lastY = e.getY(); } public void mouseDragged(MouseEvent e) { if (ren.VisibleActorCount() == 0) return; int x = e.getX(); int y = e.getY(); // rotate if (this.InteractionMode == 1) { cam.Azimuth(lastX - x); cam.Elevation(y - lastY); cam.OrthogonalizeViewUp(); resetCameraClippingRange(); if (this.LightFollowCamera == 1) { lgt.SetPosition(cam.GetPosition()); lgt.SetFocalPoint(cam.GetFocalPoint()); } } // translate if (this.InteractionMode == 2) { double FPoint[]; double PPoint[]; double APoint[] = new double[3]; double RPoint[]; double focalDepth; // get the current focal point and position FPoint = cam.GetFocalPoint(); PPoint = cam.GetPosition(); // calculate the focal depth since we'll be using it a lot ren.SetWorldPoint(FPoint[0], FPoint[1], FPoint[2], 1.0); ren.WorldToDisplay(); focalDepth = ren.GetDisplayPoint()[2]; APoint[0] = rw.GetSize()[0] / 2.0 + (x - lastX); APoint[1] = rw.GetSize()[1] / 2.0 - (y - lastY); APoint[2] = focalDepth; ren.SetDisplayPoint(APoint); ren.DisplayToWorld(); RPoint = ren.GetWorldPoint(); if (RPoint[3] != 0.0) { RPoint[0] = RPoint[0] / RPoint[3]; RPoint[1] = RPoint[1] / RPoint[3]; RPoint[2] = RPoint[2] / RPoint[3]; } /* * Compute a translation vector, moving everything 1/2 the distance * to the cursor. (Arbitrary scale factor) */ cam.SetFocalPoint((FPoint[0] - RPoint[0]) / 2.0 + FPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + FPoint[1], (FPoint[2] - RPoint[2]) / 2.0 + FPoint[2]); cam.SetPosition((FPoint[0] - RPoint[0]) / 2.0 + PPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + PPoint[1], (FPoint[2] - RPoint[2]) / 2.0 + PPoint[2]); resetCameraClippingRange(); } // zoom if (this.InteractionMode == 3) { double zoomFactor; zoomFactor = Math.pow(1.02, (y - lastY)); if (cam.GetParallelProjection() == 1) { cam.SetParallelScale(cam.GetParallelScale() / zoomFactor); } else { cam.Dolly(zoomFactor); resetCameraClippingRange(); } } lastX = x; lastY = y; this.Render(); } public void mouseWheelMoved(MouseWheelEvent e) { if (ren.VisibleActorCount() == 0 || e.getWheelRotation() == 0) return; int exponent; exponent = -10 * e.getWheelRotation() / Math.abs(e.getWheelRotation()); double zoomFactor; zoomFactor = Math.pow(1.02, exponent); if (cam.GetParallelProjection() == 1) { cam.SetParallelScale(cam.GetParallelScale() / zoomFactor); } else { cam.Dolly(zoomFactor); resetCameraClippingRange(); } this.Render(); } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { if (ren.VisibleActorCount() == 0) return; char keyChar = e.getKeyChar(); if ('r' == keyChar) { resetCamera(); this.Render(); } if ('u' == keyChar) { pickActor(lastX, lastY); } if ('w' == keyChar) { vtkActorCollection ac; vtkActor anActor; int i; ac = ren.GetActors(); ac.InitTraversal(); for (i = 0; i < ac.GetNumberOfItems(); i++) { anActor = ac.GetNextActor(); anActor.GetProperty().SetRepresentationToWireframe(); } this.Render(); } if ('s' == keyChar) { vtkActorCollection ac; vtkActor anActor; int i; ac = ren.GetActors(); ac.InitTraversal(); for (i = 0; i < ac.GetNumberOfItems(); i++) { anActor = ac.GetNextActor(); anActor.GetProperty().SetRepresentationToSurface(); } this.Render(); } } public void HardCopy(String filename, int mag) { Lock(); vtkWindowToImageFilter w2if = new vtkWindowToImageFilter(); w2if.SetInput(rw); w2if.SetScale(mag); w2if.Update(); vtkTIFFWriter writer = new vtkTIFFWriter(); writer.SetInputConnection(w2if.GetOutputPort()); writer.SetFileName(filename); writer.Write(); UnLock(); } public void pickActor(int x, int y) { vtkPropPicker picker = new vtkPropPicker(); Lock(); picker.PickProp(x, rw.GetSize()[1] - y, ren); UnLock(); if (picker.GetActor() != null) System.out.println(picker.GetActor().GetClassName()); } public void keyReleased(KeyEvent e) { } }