📄 view3dwindow.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: View3DWindow.java * Written by Gilda Garreton, Sun Microsystems. * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.plugins.j3d;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.HierarchyEnumerator;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.CodeExpression;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.plugins.j3d.utils.J3DAppearance;import com.sun.electric.plugins.j3d.utils.J3DAxis;import com.sun.electric.plugins.j3d.utils.J3DCanvas3D;import com.sun.electric.plugins.j3d.utils.J3DUtils;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.user.Highlight2;import com.sun.electric.tool.user.Highlighter;import com.sun.electric.tool.user.Resources;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.ui.*;import com.sun.j3d.utils.behaviors.interpolators.KBKeyFrame;import com.sun.j3d.utils.behaviors.interpolators.RotPosScaleTCBSplinePathInterpolator;import com.sun.j3d.utils.behaviors.interpolators.TCBKeyFrame;import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;import com.sun.j3d.utils.picking.PickCanvas;import com.sun.j3d.utils.picking.PickIntersection;import com.sun.j3d.utils.picking.PickResult;import com.sun.j3d.utils.universe.PlatformGeometry;import com.sun.j3d.utils.universe.SimpleUniverse;import com.sun.j3d.utils.universe.ViewingPlatform;import com.sun.j3d.utils.geometry.Primitive;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;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 java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.image.BufferedImage;import java.awt.image.ImageObserver;import java.awt.print.PageFormat;import java.lang.reflect.Constructor;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Observable;import java.util.Observer;import java.util.Set;import javax.media.j3d.*;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.tree.MutableTreeNode;import javax.vecmath.Matrix4d;import javax.vecmath.Point2d;import javax.vecmath.Point3d;import javax.vecmath.Quat4f;import javax.vecmath.Vector3d;import javax.vecmath.Vector3f;/** * This class deals with 3D View using Java3D * @author Gilda Garreton * @version 0.1 */public class View3DWindow extends JPanel implements WindowContent, MouseMotionListener, MouseListener, MouseWheelListener, KeyListener, ActionListener, Observer{ private SimpleUniverse u; private J3DCanvas3D canvas; protected TransformGroup objTrans; private BranchGroup scene; private OrbitBehavior orbit; // For demo cases private Map<TransformGroup,Interpolator> interpolatorMap = new HashMap<TransformGroup,Interpolator>(); private J3DKeyCollision keyBehavior; /** the window frame containing this editwindow */ private WindowFrame wf; /** reference to 2D view of the cell */ private EditWindow view2D; /** the cell that is in the window */ protected Cell cell; /** scale3D factor in Z axis */ private double scale3D = J3DUtils.get3DFactor(); /** Highlighter for this window */ private Highlighter highlighter; private PickCanvas pickCanvas; /** List with all Shape3D drawn per ElectricObject */ private Map<ElectricObject,List<Node>> electricObjectMap = new HashMap<ElectricObject,List<Node>>(); private boolean oneTransformPerNode = false; /** Map with object transformation for individual moves */ private Map<Node,TransformGroup> transformGroupMap = new HashMap<Node,TransformGroup>(); /** To detect max number of nodes */ private boolean reachLimit = false; /** To ask question only once */ private boolean alreadyChecked = false; /** Job reference */ private Job job; /** Reference to limit to consider scene graph big */ private int maxNumNodes; /** To consider a locos shape if field and gate polys are not alignedg */ private boolean locosShape; /** Inner class to create 3D view in a job. This should be safer in terms of the number of nodes * and be able to stop it */ private static class View3DWindowJob extends Job { private Cell cell; private transient WindowFrame windowFrame; private transient WindowContent view2D; private boolean transPerNode; public View3DWindowJob(Cell cell, WindowFrame wf, WindowContent view2D, boolean transPerNode) { super("3D View Job", null, Job.Type.EXAMINE, null, null, Job.Priority.USER); this.cell = cell; this.windowFrame = wf; this.view2D = view2D; this.transPerNode = transPerNode; startJob(); } public boolean doIt() throws JobException { return true; } public void terminateOK() { View3DWindow window = new View3DWindow(cell, windowFrame, view2D, transPerNode, this); windowFrame.finishWindowFrameInformation(window, cell); if (!TopLevel.isMDIMode()) { for (Component comp : windowFrame.getFrame().getToolBar().getComponents()) comp.setVisible(false); } } } public static void create3DWindow(Cell cell, WindowFrame wf, WindowContent view2D, boolean transPerNode) { new View3DWindowJob(cell, wf, view2D, transPerNode); } public void getObjTransform(Transform3D trans) { objTrans.getTransform(trans); } public void setObjTransform(Transform3D trans) { objTrans.setTransform(trans); } /** * Method to return if size limit has been reached * @param number * @return true if number of nodes is still under maximum value */ private boolean isSizeLimitOK(int number) { if (reachLimit || number > maxNumNodes) { // Only ask once if (!alreadyChecked) { String[] possibleValues = { "Full", "Limit", "Cancel" }; int response = Job.getUserInterface().askForChoice("Number of nodes in graph scene reached limit of " + maxNumNodes + " (loaded " + number + " nodes so far).\nClick 'Full' to include all nodes in " +cell + ", 'Limit' to show " + number + " nodes or 'Cancel' to abort process.\nUnexpand cells to reduce the number).", "Warning", possibleValues, possibleValues[2]); alreadyChecked = true; if (response > 0) // Cancel or limit { if (response == 2) job.abort(); reachLimit = true; } } if (reachLimit) return false; } return true; } // constructor View3DWindow(Cell cell, WindowFrame wf, WindowContent view2D, boolean transPerNode, Job job) { this.cell = cell; this.wf = wf; this.view2D = (EditWindow)view2D; // Adding observer this.view2D.getWindowFrame().addObserver(this); this.oneTransformPerNode = transPerNode; this.job = job; this.maxNumNodes = J3DUtils.get3DMaxNumNodes(); highlighter = new Highlighter(Highlighter.SELECT_HIGHLIGHTER, wf); setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); if (config == null) { GraphicsConfigTemplate3D gc3D = new GraphicsConfigTemplate3D( ); gc3D.setSceneAntialiasing( GraphicsConfigTemplate.PREFERRED ); GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment( ).getScreenDevices( ); config = gd[0].getBestConfiguration( gc3D ); } canvas = new J3DCanvas3D(config); add("Center", canvas); canvas.addMouseListener(this); // Set global appearances before create the elements J3DAppearance.setCellAppearanceValues(this); J3DAppearance.setHighlightedAppearanceValues(this); J3DAppearance.setAxisAppearanceValues(this); // Set global alpha value J3DUtils.setAlpha(J3DUtils.get3DAlpha()); // Create a simple scene and attach it to the virtual universe scene = createSceneGraph(cell); if (scene == null) return; // Have Java 3D perform optimizations on this scene graph. scene.compile(); u = new SimpleUniverse(canvas); // viewingPlatform, viewer); // lights on ViewPlatform geometry group PlatformGeometry pg = new PlatformGeometry(); J3DUtils.createLights(pg); ViewingPlatform viewingPlatform = u.getViewingPlatform(); // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. viewingPlatform.setNominalViewingTransform(); orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL); orbit.setSchedulingBounds(J3DUtils.infiniteBounds); orbit.setCapability(OrbitBehavior.ALLOW_LOCAL_TO_VWORLD_READ); /** Setting rotation center */ Point3d center = new Point3d(0, 0, 0); BoundingSphere sceneBnd = (BoundingSphere)scene.getBounds(); sceneBnd.getCenter(center); orbit.setRotationCenter(center); orbit.setMinRadius(0);// orbit.setZoomFactor(10);// orbit.setTransFactors(10, 10); orbit.setProportionalZoom(true); viewingPlatform.setNominalViewingTransform(); viewingPlatform.setViewPlatformBehavior(orbit); double radius = sceneBnd.getRadius(); View view = u.getViewer().getView(); // Too expensive at this point if (canvas.getSceneAntialiasingAvailable() && J3DUtils.is3DAntialiasing()) view.setSceneAntialiasingEnable(true); // Setting the projection policy view.setProjectionPolicy(J3DUtils.is3DPerspective()? View.PERSPECTIVE_PROJECTION : View.PARALLEL_PROJECTION); if (!J3DUtils.is3DPerspective()) view.setCompatibilityModeEnable(true); // Setting transparency sorting view.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_GEOMETRY); view.setDepthBufferFreezeTransparent(false); // set to true only for transparent layers // Setting a good viewpoint for the camera Vector3d vCenter = new Vector3d(center); double vDist = 1.4 * radius / Math.tan(view.getFieldOfView()/2.0); vCenter.z += vDist; Transform3D vTrans = new Transform3D(); //translateB.setView(cellBnd.getWidth(), 0); //double[] rotVals = User.transformIntoValues(User.get3DRotation()); //rotateB.setRotation(rotVals[0], rotVals[1], rotVals[2]); //zoomB.setZoom(User.get3DOrigZoom()); vTrans.setTranslation(vCenter); view.setBackClipDistance((vDist+radius)*200.0); view.setFrontClipDistance((vDist+radius)/200.0);// view.setBackClipPolicy(View.VIRTUAL_EYE);// view.setFrontClipPolicy(View.VIRTUAL_EYE); if (J3DUtils.is3DPerspective()) { //keyBehavior.setHomeRotation(User.transformIntoValues(J3DUtils.get3DRotation())); viewingPlatform.getViewPlatformBehavior().setHomeTransform(vTrans); viewingPlatform.getViewPlatformBehavior().goHome(); //viewingPlatform.getViewPlatformTransform().setTransform(vTrans); } else { Transform3D proj = new Transform3D(); Rectangle2D cellBnd = cell.getBounds(); proj.ortho(cellBnd.getMinX(), cellBnd.getMinX(), cellBnd.getMinY(), cellBnd.getMaxY(), (vDist+radius)/200.0, (vDist+radius)*2.0); view.setVpcToEc(proj); //viewingPlatform.getViewPlatformTransform().setTransform(lookAt); } u.addBranchGraph(scene); // Create axis with associated behavior BranchGroup axisRoot = new BranchGroup();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -