edu.uci.ics.jung.visualization3d.VisualizationViewer Maven / Gradle / Ivy
/*
* Copyright (c) 2003, the JUNG Project and the Regents of the University of
* California All rights reserved.
*
* This software is open-source under the BSD license; see either "license.txt"
* or http://jung.sourceforge.net/license.txt for a description.
*/
package edu.uci.ics.jung.visualization3d;
/**
*
*/
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GraphicsConfiguration;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;
import java.util.Map;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Bounds;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Font3D;
import javax.media.j3d.FontExtrusion;
import javax.media.j3d.Group;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.OrientedShape3D;
import javax.media.j3d.Text3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import org.apache.commons.collections15.BidiMap;
import org.apache.commons.collections15.bidimap.DualHashBidiMap;
import com.sun.j3d.utils.behaviors.mouse.MouseWheelZoom;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.picking.PickTool;
import com.sun.j3d.utils.picking.behaviors.PickingCallback;
import com.sun.j3d.utils.universe.SimpleUniverse;
import edu.uci.ics.jung.algorithms.layout.util.VisRunner;
import edu.uci.ics.jung.algorithms.layout3d.Layout;
import edu.uci.ics.jung.algorithms.util.IterativeContext;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.Context;
import edu.uci.ics.jung.graph.util.Pair;
import edu.uci.ics.jung.visualization.picking.MultiPickedState;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization3d.control.MouseRotate;
import edu.uci.ics.jung.visualization3d.control.MouseTranslate;
import edu.uci.ics.jung.visualization3d.control.PickSphereBehavior;
import edu.uci.ics.jung.visualization3d.control.PickTranslateBehavior;
import edu.uci.ics.jung.visualization3d.layout.LayoutEventBroadcaster;
/**
*
* @author Tom Nelson - [email protected]
*
*/
public class VisualizationViewer extends JPanel {
BranchGroup objRoot;
TransformGroup objTrans;
// Appearance vertexLook;
// Appearance edgeLook;
Appearance grayLook;
/**
* a listener used to cause pick events to result in
* repaints, even if they come from another view
*/
protected ItemListener pickEventListener;
/**
* holds the state of which vertices of the graph are
* currently 'picked'
*/
protected PickedState pickedVertexState;
/**
* holds the state of which edges of the graph are
* currently 'picked'
*/
protected PickedState pickedEdgeState;
protected RenderContext renderContext = new PluggableRenderContext();
BidiMap vertexMap = new DualHashBidiMap();
Map edgeMap = new HashMap();
Graph graph;
Layout layout;
public VisualizationViewer() {
// controls = createControls();
setLayout(new BorderLayout());
renderContext.setPickedVertexState(new MultiPickedState());
renderContext.setPickedEdgeState(new MultiPickedState());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
final Canvas3D c = new Canvas3D(config);
add(c, BorderLayout.CENTER);
setPickedVertexState(new MultiPickedState());
setPickedEdgeState(new MultiPickedState());
// Create a SpringGraph scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph(c);
SimpleUniverse u = new SimpleUniverse(c);
u.getViewer().getView().setUserHeadToVworldEnable(true);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public Layout getGraphLayout() {
return layout;
}
public BranchGroup createSceneGraph(final Canvas3D canvas) {
objRoot = new BranchGroup();
objRoot.setCapability(Group.ALLOW_CHILDREN_EXTEND);
objRoot.setCapability(Group.ALLOW_CHILDREN_WRITE);
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
// t3d.setScale(0.05);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
Transform3D tt = new Transform3D();
tt.setScale(.05);
tt.setTranslation(new Vector3f(0, 0, -30.f));
objTrans = new TransformGroup(tt);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ );
objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
objScale.addChild(objTrans);
// objRoot.addChild(objTrans);
// Create Colors, Materials, and Appearances.
Appearance look = new Appearance();
Color3f objColor = new Color3f(0.7f, 0.7f, 0.7f);
Color3f black = new Color3f(0.f, 0.f, 0.f);
Color3f white = new Color3f(1.0f, 1.0f, 0.6f);
Color3f gray = new Color3f(.2f, .2f, .2f);
Color3f red = new Color3f(1.0f, 0, 0);
Color3f yellow = new Color3f(1,1,0);
Material objMaterial = new Material(objColor, black,
objColor, white, 100.0f);
Material blackMaterial = new Material(objColor, black,
black, objColor, 10.0f);
Material whiteMaterial = new Material(white, white,
white, white, 100.0f);
Material grayMaterial = new Material(gray, black,
gray, gray, 100.0f);
Material redMaterial = new Material(red, black,
red, red, 100.0f);
Material yellowMaterial = new Material(yellow, black,
yellow, yellow, 100);
look.setMaterial(new Material(objColor, black,
objColor, white, 100.0f));
Appearance blackLook = new Appearance();
blackLook.setMaterial(blackMaterial);
Appearance whiteLook = new Appearance();
whiteLook.setMaterial(whiteMaterial);
Appearance grayLook = new Appearance();
grayLook.setMaterial(grayMaterial);
grayLook.setCapability(Appearance.ALLOW_MATERIAL_READ);
grayLook.setCapability(Appearance.ALLOW_MATERIAL_WRITE);
final Appearance redLook = new Appearance();
redLook.setMaterial(redMaterial);
// vertexLook = redLook;
Appearance objLook = new Appearance();
objLook.setMaterial(objMaterial);
grayLook = objLook;
final Appearance yellowLook = new Appearance();
yellowLook.setMaterial(yellowMaterial);
Bounds bounds =
new BoundingSphere(new Point3d(),
300);
MouseRotate behavior1 = new MouseRotate();
behavior1.setTransformGroup(objTrans);
objTrans.addChild(behavior1);
behavior1.setSchedulingBounds(bounds);
MouseWheelZoom behavior2 = new MouseWheelZoom();
behavior2.setTransformGroup(objTrans);
// behavior2.setFactor(10);
objTrans.addChild(behavior2);
behavior2.setSchedulingBounds(bounds);
MouseTranslate behavior3 = new MouseTranslate();
behavior3.setTransformGroup(objTrans);
objTrans.addChild(behavior3);
behavior3.setSchedulingBounds(bounds);
PickTranslateBehavior ptb = new PickTranslateBehavior(objRoot,canvas,bounds,PickTool.GEOMETRY);
ptb.setSchedulingBounds(bounds);
// objTrans.addChild(ptb);
ptb.setupCallback(new PickingCallback() {
public void transformChanged(int type, TransformGroup tg) {
if(tg == null) return;
Transform3D t3d = new Transform3D();
tg.getTransform(t3d);
// System.err.println(tg+" transformChanged \n"+t3d);
Point3f p1 = new Point3f();
V v = vertexMap.getKey(tg);
// Transform3D lvw = new Transform3D();
// tg.getLocalToVworld(lvw);
// System.err.println("lvw = \n"+lvw);
// lvw.invert();
// System.err.println("invert lvw = \n"+lvw);
Point3f p0 = layout.transform(v);
// Transform3D vwip = new Transform3D();
// canvas.getVworldToImagePlate(vwip);
// System.err.println("vwip=\n"+vwip);
// t3d.mul(lvw);
t3d.transform(p1);
// scale.transform(p1);
System.err.println("change location for vertex "+v+", transformGroup "+tg+" from "+p0+" to "+p1);
// p1.set(p1.getX()*2,p1.getY()*2,p1.getZ()*2);
// layout.setLocation(v, p1);
}});
PickSphereBehavior psb = new PickSphereBehavior(objRoot,canvas,bounds);
PickVertexBehavior pvb = new PickVertexBehavior(objRoot,canvas,bounds,renderContext.getPickedVertexState());
objTrans.addChild(pvb);
pvb.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
for(V v : graph.getVertices()) {
VertexGroup vg = vertexMap.get(v);
Appearance look = redLook;
if(renderContext.getPickedVertexState().isPicked(v)) {
look = yellowLook;
}
Node node = vg.getShape();
if(node instanceof Primitive) {
((Primitive)node).setAppearance(look);
}
}
}});
//Shine it with two colored lights.
Color3f lColor1 = new Color3f(.5f, .5f, .5f);
Color3f lColor2 = new Color3f(1.0f, 1.0f, 1.0f);
Vector3f lDir2 = new Vector3f(-1.0f, 0.0f, -1.0f);
DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
AmbientLight ambient = new AmbientLight(lColor1);
lgt2.setInfluencingBounds(bounds);
ambient.setInfluencingBounds(bounds);
objRoot.addChild(lgt2);
objRoot.addChild(ambient);
// Let Java 3D perform optimizations on this scene graph.
objRoot.compile();
// VisRunner runner = new VisRunner((IterativeContext)elayout);
// runner.relax();
return objRoot;
}
public void setGraphLayout(Layout inLayout) {
// this.layout = inLayout;
this.graph = inLayout.getGraph();
BranchGroup branch = new BranchGroup();
LayoutEventBroadcaster elayout =
new LayoutEventBroadcaster(inLayout);
this.layout = elayout;
for(V v : graph.getVertices()) {
VertexGroup vg = new VertexGroup(v, renderContext.getVertexShapeTransformer().transform(v));
vg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
vg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
vertexMap.put(v, vg);
branch.addChild(vg);
String label = renderContext.getVertexStringer().transform(v);
if(label != null) {
String fontName = "Serif";
Font3D f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
new FontExtrusion());
Text3D txt = new Text3D(f3d, label,
new Point3f(2f,2f,0));
OrientedShape3D textShape = new OrientedShape3D();
textShape.setGeometry(txt);
textShape.setAppearance(grayLook);
// textShape.setAlignmentAxis( 0.0f, 1.0f, 0.0f);
textShape.setAlignmentMode(OrientedShape3D.ROTATE_ABOUT_POINT);
textShape.setRotationPoint(new Point3f());
// objScale.addChild( textShape );
// BranchGroup bg = new BranchGroup();
// bg.addChild(textShape);
// branch.addChild(bg);
// Text2D text = new Text2D(label+" more text here", new Color3f(0,0,0),"Serif",50,Font.BOLD);
Transform3D tt = new Transform3D();
// tt.setTranslation(new Vector3f(100,100,100));
tt.setScale(5);
TransformGroup tg = new TransformGroup(tt);
// textShape.setGeometry(text);
tg.addChild(textShape);
BranchGroup bg = new BranchGroup();
bg.addChild(tg);
// branch.addChild(bg);
vg.getLabelNode().addChild(bg);
}
}
System.err.println("vertexMap = "+vertexMap);
for(E edge : graph.getEdges()) {
EdgeGroup eg =
new EdgeGroup(edge, renderContext.getEdgeShapeTransformer().transform(Context.,E>getInstance(graph, edge)));
eg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
eg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
edgeMap.put(edge, eg);
branch.addChild(eg);
}
// System.err.println("branch is "+branch);
// for(int i=0; i endpoints = graph.getEndpoints(edge);
V start = endpoints.getFirst();
V end = endpoints.getSecond();
EdgeGroup eg = edgeMap.get(edge);
eg.setEndpoints(layout.transform(start), layout.transform(end));
}
}});
elayout.setSize(new BoundingSphere(new Point3d(), 200));
elayout.initialize();
VisRunner runner = new VisRunner((IterativeContext)elayout);
runner.relax();
// for(int i=0; i pickedVertexState) {
if(pickEventListener != null && this.pickedVertexState != null) {
this.pickedVertexState.removeItemListener(pickEventListener);
}
this.pickedVertexState = pickedVertexState;
this.renderContext.setPickedVertexState(pickedVertexState);
if(pickEventListener == null) {
pickEventListener = new ItemListener() {
public void itemStateChanged(ItemEvent e) {
System.err.println(e.getItem()+" was picked");
}
};
}
pickedVertexState.addItemListener(pickEventListener);
}
/* (non-Javadoc)
* @see edu.uci.ics.jung.visualization.VisualizationServer#setPickedEdgeState(edu.uci.ics.jung.visualization.picking.PickedState)
*/
public void setPickedEdgeState(PickedState pickedEdgeState) {
if(pickEventListener != null && this.pickedEdgeState != null) {
this.pickedEdgeState.removeItemListener(pickEventListener);
}
this.pickedEdgeState = pickedEdgeState;
this.renderContext.setPickedEdgeState(pickedEdgeState);
if(pickEventListener == null) {
pickEventListener = new ItemListener() {
public void itemStateChanged(ItemEvent e) {
repaint();
}
};
}
pickedEdgeState.addItemListener(pickEventListener);
}
/**
* @return the renderContext
*/
public RenderContext getRenderContext() {
return renderContext;
}
// public static void main(String argv[])
// {
// final VisualizationViewer enigma = new VisualizationViewer();
// JFrame f = new JFrame();
// f.add(enigma);
// f.setSize(600,600);
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//// new MainFrame(enigma, 500, 500);
//// f.pack();
// f.setVisible(true);
// }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy