📄 view3dwindow.java
字号:
double dist = (layer.getDistance() + layer.getThickness()) * scale3D; double distPoly = (polys[poly].getLayer().getDistance()) * scale3D; Point2D pointDist, pointClose; List<Point3d> topList = new ArrayList<Point3d>(); List<Point3d> bottomList = new ArrayList<Point3d>(); int center, right; if (dist1 > dist2) { pointDist = p1; pointClose = p2; center = 1; right = 2; } else { pointDist = p2; pointClose = p1; center = 2; right = points.length-1; } Point2d pDelta = new Point2d(pointDist.getX()-points[0].getX(), pointDist.getY()-points[0].getY()); pDelta.scale(0.1); double[] values = new double[2]; pDelta.get(values); // First extra polyhedron topList.add(new Point3d(p0.getX()+values[0], p0.getY()+values[1], dist)); topList.add(new Point3d(p0.getX(), p0.getY(), distPoly)); topList.add(new Point3d(p0.getX()-values[0], p0.getY()-values[1], distPoly)); topList.add(new Point3d(p0.getX(), p0.getY(), dist)); bottomList.add(new Point3d(pointClose.getX()+values[0], pointClose.getY()+values[1], dist)); bottomList.add(new Point3d(pointClose.getX(), pointClose.getY(), distPoly)); bottomList.add(new Point3d(pointClose.getX()-values[0], pointClose.getY()-values[1], distPoly)); bottomList.add(new Point3d(pointClose.getX(), pointClose.getY(), dist)); J3DUtils.correctNormals(topList, bottomList); System.arraycopy(topList.toArray(), 0, pts, 0, 4); System.arraycopy(bottomList.toArray(), 0, pts, 4, 4); boxList.add(J3DUtils.addShape3D(pts, 4, J3DAppearance.getAppearance(layer.getGraphics()), objTrans)); // Second polyhedron topList.clear(); bottomList.clear(); topList.add(new Point3d(points[center].getX()-values[0], points[center].getY()-values[1], dist)); topList.add(new Point3d(points[center].getX(), points[center].getY(), distPoly)); topList.add(new Point3d(points[center].getX()+values[0], points[center].getY()+values[1], distPoly)); topList.add(new Point3d(points[center].getX(), points[center].getY(), dist)); bottomList.add(new Point3d(points[right].getX()-values[0], points[right].getY()-values[1], dist)); bottomList.add(new Point3d(points[right].getX(), points[right].getY(), distPoly)); bottomList.add(new Point3d(points[right].getX()+values[0], points[right].getY()+values[1], distPoly)); bottomList.add(new Point3d(points[right].getX(), points[right].getY(), dist)); J3DUtils.correctNormals(topList, bottomList); System.arraycopy(topList.toArray(), 0, pts, 0, 4); System.arraycopy(bottomList.toArray(), 0, pts, 4, 4); boxList.add(J3DUtils.addShape3D(pts, 4, J3DAppearance.getAppearance(layer.getGraphics()), objTrans)); } if (boxList != null) list.addAll(boxList); } if (list.isEmpty()) System.out.println("No layer with non-zero thickness found in node '" + no.getName() + "'"); else { electricObjectMap.put(no, list); for (int i = 0; i < list.size(); i++) { transformGroupMap.put(list.get(i), objTrans); } } } /** * Adds given list of Polys representing a PrimitiveNode to the transformation group * @param polys * @param transform * @param objTrans */ private List<Node> addPolys(Poly [] polys, AffineTransform transform, TransformGroup objTrans) { if (polys == null) return (null); List<Node> list = new ArrayList<Node>(); for(int i = 0; i < polys.length; i++) { Poly poly = polys[i]; if (poly == null) continue; // Case for transistors and active regions. Layer layer = poly.getLayer(); if (layer == null || layer.getTechnology() == null) continue; // Non-layout technology. E.g Artwork if (!layer.isVisible()) continue; // Doesn't generate the graph double thickness = layer.getThickness() * scale3D; double distance = layer.getDistance() * scale3D; if (thickness == 0) continue; // Skip zero-thickness layers if (transform != null) poly.transform(transform); // Setting appearance J3DAppearance ap = J3DAppearance.getAppearance(layer.getGraphics()); Poly.Type type = poly.getStyle(); switch (type) { case FILLED: case CLOSED: // polygon cases if (poly.getBox() == null) // non-manhattan shape { list.add(J3DUtils.addPolyhedron(poly.getPathIterator(null), distance, thickness, ap, objTrans)); } else { Rectangle2D bounds = poly.getBounds2D(); list.add(J3DUtils.addPolyhedron(bounds, distance, thickness, ap, objTrans)); } break; case CIRCLE: case DISC: list.add(J3DUtils.addCylinder(poly.getPoints(), distance, thickness, ap, objTrans)); break; default: System.out.println("Case not implemented in View3DDWindow.addPolys"); } } return (list); } /******************************************************************************************************** * Model-View paradigm to control refresh from 2D ********************************************************************************************************/ /** * Internal method to hightlight objects * @param toSelect true if element must be highlighted * @param do2D true if 2D highlighter should be called */ private void selectObject(boolean toSelect, boolean do2D) { Highlighter highlighter2D = null; // Clean previous selection if (view2D != null && do2D) { highlighter2D = view2D.getHighlighter(); highlighter2D.clear(); } for (Highlight2 h : highlighter.getHighlights()) { HighlightShape3D hObj = (HighlightShape3D)(h.getObject());// Node obj = hObj.shape; if (toSelect) // highlight cell, set transparency { //J3DAppearance app = (J3DAppearance)obj.getAppearance(); hObj.setAppearance(J3DAppearance.highlightApp); //app.getRenderingAttributes().setVisible(false); //J3DAppearance.highlightApp.setGraphics(app.getGraphics()); if (view2D != null && do2D) { //Geometry geo = obj.getGeometry(); BoundingBox bb = (BoundingBox)hObj.shape.getBounds(); Point3d lowerP = new Point3d(), upperP = new Point3d(); bb.getUpper(upperP); bb.getLower(lowerP); double[] lowerValues = new double[3]; double[] upperValues = new double[3]; lowerP.get(lowerValues); upperP.get(upperValues); Rectangle2D area = new Rectangle2D.Double(lowerValues[0], lowerValues[1], (upperValues[0]-lowerValues[0]), (upperValues[1]-lowerValues[1])); highlighter2D.addArea(area, cell); } } else // back to normal { //EGraphics graphics = J3DAppearance.highlightApp.getGraphics(); if (hObj.origApp != null) //if (graphics != null) { //J3DAppearance origAp = (J3DAppearance)graphics.get3DAppearance(); hObj.setAppearance(hObj.origApp); } else // its a cell hObj.setAppearance(J3DAppearance.cellApp); } } if (!toSelect) highlighter.clear(); if (do2D) view2D.fullRepaint(); } /** * Observer method to highlight 3D nodes by clicking 2D objects * @param o * @param arg */ public void update(Observable o, Object arg) { // Undo previous highlight selectObject(false, false); if (o == view2D.getWindowFrame()) { Highlighter highlighter2D = view2D.getHighlighter(); List<Geometric> geomList = highlighter2D.getHighlightedEObjs(true, true); for (Geometric geom : geomList) { ElectricObject eobj = geom; List<Node> list = electricObjectMap.get(eobj); if (list == null || list.size() == 0) continue; for (Node shape : list) { highlighter.addObject(new HighlightShape3D(shape), cell); } } selectObject(true, false); return; // done } } /** This class will help to remember original appearance of the node * */ private static class HighlightShape3D { Node shape; Appearance origApp; HighlightShape3D(Node n) { this.shape = n; this.origApp = getAppearance(n); } static Appearance getAppearance(Node n) { if (n instanceof Shape3D) return ((Shape3D)n).getAppearance(); else if (n instanceof Primitive) return ((Primitive)n).getAppearance(); else assert(false); // it should not happen return null; } void setAppearance(Appearance a) { if (shape instanceof Shape3D) ((Shape3D)shape).setAppearance(a); else if (shape instanceof Primitive) ((Primitive)shape).setAppearance(a); else assert(false); // it should not happen } } /** * Method to change Z values in elements * @param value */ public static void setScaleFactor(double value) { Transform3D vTrans = new Transform3D(); Vector3d vCenter = new Vector3d(1, 1, value); for(Iterator<WindowFrame> it = WindowFrame.getWindows(); it.hasNext(); ) { WindowFrame wf = it.next(); WindowContent content = wf.getContent(); if (!(content instanceof View3DWindow)) continue; View3DWindow wnd = (View3DWindow)content; wnd.objTrans.getTransform(vTrans); vTrans.setScale(vCenter); wnd.objTrans.setTransform(vTrans); } } /** * Method to turn on/off antialiasing * @param value true if antialiasing is set to true */ public static void setAntialiasing(boolean value) { for(Iterator<WindowFrame> it = WindowFrame.getWindows(); it.hasNext(); ) { WindowFrame wf = it.next(); WindowContent content = wf.getContent(); if (!(content instanceof View3DWindow)) continue; View3DWindow wnd = (View3DWindow)content; View view = wnd.u.getViewer().getView(); view.setSceneAntialiasingEnable(value); } } /** * Method to change geometry of all nodes using this particular layer * This could be an expensive function!. * @param layer * @param distance * @param thickness */ public static void setZValues(Layer layer, Double origDist, Double origThick, Double distance, Double thickness) { for(Iterator<WindowFrame> it = WindowFrame.getWindows(); it.hasNext(); ) { WindowFrame wf = it.next(); WindowContent content = wf.getContent(); if (!(content instanceof View3DWindow)) continue; View3DWindow wnd = (View3DWindow)content; for (int i = 0; i < wnd.objTrans.numChildren(); i++) { Node node = wnd.objTrans.getChild(i); if (node instanceof Shape3D) { Shape3D shape = (Shape3D)node; J3DAppearance app = (J3DAppearance)shape.getAppearance(); if (app.getGraphics().getLayer() == layer) J3DUtils.updateZValues(shape, origDist.floatValue(), (float)(origDist.floatValue()+origThick.floatValue()), distance.floatValue(), (float)(distance.floatValue()+thickness.floatValue())); } } } } /** * Method to export directly PNG file * @param ep * @param filePath */ public void writeImage(ElectricPrinter ep, String filePath) { canvas.filePath = filePath; saveImage(false); } public void saveImage(boolean movieMode) { canvas.movieMode = movieMode; canvas.writePNG_ = true; canvas.repaint(); } /** * Method to intialize for printing.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -