📄 view3dwindow.java
字号:
// Position the axis Transform3D t = new Transform3D();// t.set(new Vector3d(-0.9, -0.5, -2.5)); // set on Linux t.set(new Vector3d(-radius/10, -radius/16, -radius/3.5)); TransformGroup axisTranslation = new TransformGroup(t); axisRoot.addChild(axisTranslation); // Create the axis behavior // Using reflection to create this behavior because Java3D plugin // might not be available. Reflection would have to be here until Java3D team // releases this new behavior Class plugin = Resources.getJMFJ3DClass("J3DAxisBehavior"); if (plugin == null) { if (Job.getDebug()) System.out.println("Java3D plugin not available. 3D axes not created."); } else { // Create transform group to orient the axis and make it // readable & writable (this will be the target of the axis // behavior) TransformGroup axisTG = new TransformGroup(); axisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); axisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); axisTranslation.addChild(axisTG); // Create the axis geometry J3DAxis axis = new J3DAxis(radius/10, J3DAppearance.axisApps[0], J3DAppearance.axisApps[1], J3DAppearance.axisApps[2], User.getDefaultFont()); axisTG.addChild(axis); // Add axis into BG pg.addChild(axisRoot); TransformGroup viewPlatformTG = viewingPlatform.getViewPlatformTransform(); try { Constructor instance = plugin.getDeclaredConstructor(new Class[]{TransformGroup.class, TransformGroup.class}); Object obj = instance.newInstance(new Object[] {axisTG, viewPlatformTG}); if (obj != null) { Behavior axisBehavior = (Behavior)obj; //new J3DAxisBehavior(axisTG, viewPlatformTG); axisBehavior.setSchedulingBounds(J3DUtils.infiniteBounds); pg.addChild(axisBehavior); } } catch (Exception e) { e.printStackTrace(); } } viewingPlatform.setPlatformGeometry(pg) ; setWindowTitle(); } /** * Method to create main transformation group * @param cell * @return BrachGroup representing the scene graph */ protected BranchGroup createSceneGraph(Cell cell) { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); objRoot.setCapability(BranchGroup.ALLOW_BOUNDS_READ); objRoot.setCapability(BranchGroup.ENABLE_PICK_REPORTING); objRoot.setCapability(BranchGroup.ALLOW_BOUNDS_WRITE); // Create a Transformgroup to scale all objects so they // appear in the scene. TransformGroup objScale = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setScale(0.7); objScale.setTransform(t3d); objRoot.addChild(objScale); // Create the TransformGroup node and initialize it to the // identity. Enable the TRANSFORM_WRITE capability so that // our behavior code can modify it at run time. Add it to // the root of the subgraph. objTrans = new TransformGroup(); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND); objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_READ); objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE); objTrans.setCapability(TransformGroup.ALLOW_BOUNDS_READ); //objRoot.addChild(objTrans); objScale.addChild(objTrans); // Background J3DUtils.createBackground(objRoot); View3DEnumerator view3D = new View3DEnumerator(cell); HierarchyEnumerator.enumerateCell(cell, VarContext.globalContext, view3D);// HierarchyEnumerator.enumerateCell(cell, VarContext.globalContext, null, view3D); if (electricObjectMap.isEmpty()) System.out.println("No 3D elements added. Check 3D values."); if (job.checkAbort()) return null; // Job cancel // Picking tools pickCanvas = new PickCanvas(canvas, objRoot); pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO); pickCanvas.setTolerance(4.0f); setInterpolator(); // create the KeyBehavior and attach main transformation group keyBehavior = new J3DKeyCollision(objTrans, this); keyBehavior.setSchedulingBounds(J3DUtils.infiniteBounds); objTrans.addChild(keyBehavior); return objRoot; } /** * Method to set the window title. */ public void setWindowTitle() { if (wf == null) return; wf.setTitle(wf.composeTitle(cell, "3D View: ", 0)); } /** * Method to return the cell that is shown in this window. * @return the cell that is shown in this window. */ public Cell getCell() { return cell; } /** * Method to get rid of this EditWindow. Called by WindowFrame when * that windowFrame gets closed. */ public void finished() { // remove myself from listener list removeKeyListener(this); removeMouseListener(this); removeMouseMotionListener(this); removeMouseWheelListener(this); } public void bottomScrollChanged(int e) {} public void rightScrollChanged(int e) {} /** Dummy functios due to text-oriented functions */ public void fullRepaint() {} public boolean findNextText(boolean reverse) { return false; } public void replaceText(String replace) {} public JPanel getPanel() { return this; } public void initTextSearch(String search, boolean caseSensitive, boolean regExp, Set<TextUtils.WhatToSearch> whatToSearch, CodeExpression.Code codeRestr, TextDescriptor.Unit unitRestr, boolean highlightedOnly) {} /** * Method to pan along X according to fixed amount of ticks * @param direction * @param panningAmounts * @param ticks */ public void panXOrY(int direction, double[] panningAmounts, int ticks) { Cell cell = getCell(); if (cell == null) return; double panningAmount = panningAmounts[User.getPanningDistance()]; int mult = (int)((double)10 * panningAmount); if (mult == 0) mult = 1; keyBehavior.moveAlongAxis(direction, mult*ticks); } /** * Method to shift the panels so that the current cursor location becomes the center. */ public void centerCursor() { }// public void setViewAndZoom(double x, double y, double zoom)// {//// translateB.setView(x, y);// } /** * Method to zoom out by a factor of 2 plus mouse pre-defined factor */ public void zoomOutContents() { keyBehavior.zoomInOut(false);// zoomB.zoomInOut(false); } /** * Method to zoom in by a factor of 2 plus mouse pre-defined factor */ public void zoomInContents() { keyBehavior.zoomInOut(true); //zoomB.zoomInOut(true); } /** * Method to reset zoom/rotation/extraTrans to original place (Fill Window operation) */ public void fillScreen() { objTrans.setTransform(new Transform3D()); u.getViewingPlatform().getViewPlatformBehavior().goHome(); } public void setCell(Cell cell, VarContext context, WindowFrame.DisplayAttributes da) {} public void focusOnHighlighted() {} public void replaceAllText(String replace) {} public Highlighter getHighlighter() { return highlighter; } /** * */ public List<MutableTreeNode> loadExplorerTrees() { return wf.loadDefaultExplorerTree(); } /** * Adds given Arc to scene graph * @param ai * @param objTrans */ public void addArc(ArcInst ai, AffineTransform transform, TransformGroup objTrans) { // add the arc ArcProto ap = ai.getProto(); Technology tech = ap.getTechnology(); List<Node> list = addPolys(tech.getShapeOfArc(ai), transform, objTrans); if (list.isEmpty()) System.out.println("No layer with non-zero thickness found in arc '" + ai.getName() + "'"); else electricObjectMap.put(ai, list); } /** * Adds given Node to scene graph * @param no * @param objTrans */ private void addNode(NodeInst no, AffineTransform transform, TransformGroup objTrans) { // add the node NodeProto nProto = no.getProto(); Technology tech = nProto.getTechnology(); int gate = -1; int count = 0; int poly = -1; // Skipping Special nodes if (NodeInst.isSpecialNode(no)) return; List<Node> list = null; if (no.isCellInstance()) { // Cell Cell cell = (Cell)nProto; Rectangle2D rect = no.getBounds(); double [] values = new double[2]; values[0] = Double.MAX_VALUE; values[1] = Double.MIN_VALUE; cell.getZValues(values); values[0] *= scale3D; values[1] *= scale3D; Poly pol = new Poly(rect); list = new ArrayList<Node>(1); if (transform.getType() != AffineTransform.TYPE_IDENTITY) pol.transform(transform); rect = pol.getBounds2D(); list.add(J3DUtils.addPolyhedron(rect, values[0], values[1] - values[0], J3DAppearance.cellApp, objTrans)); } else { Poly[] polys = tech.getShapeOfNode(no, true, true, null); List<Shape3D> boxList = null; // Special case for transistors if (nProto.getFunction().isTransistor()) { int[] active = new int[2]; boolean isSerpentine = no.isSerpentineTransistor(); boxList = new ArrayList<Shape3D>(4); // Merge active regions for (int i = 0; i < polys.length; i++) { Layer.Function fun = polys[i].getLayer().getFunction(); if (!isSerpentine && fun.isDiff()) { // The 3D code will merge the active only for simple transistors. // Only 2 active regions are allowed for non-serpentine if (count > 1) System.out.println("More than 2 active regions detected in Transistor '" + no.getName() + "'. Ignoring this layer"); else active[count++] = i; } else if (fun.isGatePoly()) gate = i; else if (fun.isPoly()) poly = i; } if (count == 2) { Rectangle2D rect1 = polys[active[0]].getBounds2D(); Rectangle2D rect2 = polys[active[1]].getBounds2D(); double minX = Math.min(rect1.getMinX(), rect2.getMinX()); double minY = Math.min(rect1.getMinY(), rect2.getMinY()); double maxX = Math.max(rect1.getMaxX(), rect2.getMaxX()); double maxY = Math.max(rect1.getMaxY(), rect2.getMaxY()); Rectangle2D newRect = new Rectangle2D.Double(minX, minY, (maxX-minX), (maxY-minY)); Poly tmp = new Poly(newRect); tmp.setLayer(polys[active[0]].getLayer()); polys[active[0]] = tmp; // new active with whole area beneath poly gate int last = polys.length - 1; if (active[1] != last) polys[active[1]] = polys[last]; polys[last] = null; } } list = addPolys(polys, transform, objTrans); // Adding extra layers after polygons are rotated. if (locosShape && nProto.getFunction().isTransistor() && gate != -1 && poly != -1) { Point3d [] pts = new Point3d[8]; Point2D[] points = polys[gate].getPoints(); Point2D p0 = points[0]; Point2D p1 = points[1]; Point2D p2 = points[points.length-1]; double dist1 = p0.distance(p1); double dist2 = p0.distance(p2); Layer layer = polys[gate].getLayer();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -