📄 arcinst.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ArcInst.java * * 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.database.topology;import com.sun.electric.database.EObjectInputStream;import com.sun.electric.database.EObjectOutputStream;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.constraint.Constraints;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.id.CellId;import com.sun.electric.database.id.PrimitivePortId;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.Name;import com.sun.electric.database.variable.DisplayedText;import com.sun.electric.database.variable.EditWindow0;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.BoundsBuilder;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.TechPool;import com.sun.electric.technology.Technology;import com.sun.electric.tool.Job;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.tool.user.User;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.geom.AffineTransform;import java.io.IOException;import java.io.InvalidObjectException;import java.io.NotSerializableException;import java.util.List;import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;/** * An ArcInst is an instance of an ArcProto (a wire type) * An ArcInst points to its prototype, the Cell on which it has been * instantiated, and the connection at either end of the wire. * The geometry of the wire (width and length) is captured in the * bounds of the Geometric portion of this object. * <P> * ArcInst objects have properties that constrain them. Here is the notion of "Fixed angle": * <P> * <CENTER><IMG SRC="doc-files/ArcInst-1.gif"></CENTER> * <P> * Here is the notion of rigid arcs: * <P> * <CENTER><IMG SRC="doc-files/ArcInst-2.gif"></CENTER> * <P> * Here is the notion of slidable arcs: * <P> * <CENTER><IMG SRC="doc-files/ArcInst-3.gif"></CENTER> * <P> * Constraints propagate hierarchically: * <P> * <CENTER><IMG SRC="doc-files/ArcInst-4.gif"></CENTER> */public class ArcInst extends Geometric implements Comparable<ArcInst>{ /** empty array of ArcInsts. */ public static final ArcInst[] NULL_ARRAY = {}; /** The index of the tail of this ArcInst. */ public static final int TAILEND = ImmutableArcInst.TAILEND; /** The index of the head of this ArcInst. */ public static final int HEADEND = ImmutableArcInst.HEADEND; /** Key of the obsolete variable holding arc name.*/public static final Variable.Key ARC_NAME = Variable.newKey("ARC_name"); /** Minimal distance of arc end to port polygon. */ static final double MINPORTDISTANCE = DBMath.getEpsilon()*0.71; // sqrt(0.5) // -------------------------- private data ---------------------------------- /** Owner of this ArcInst. */ private final Topology topology; /** persistent data of this ArcInst. */ ImmutableArcInst d; /** bounds after transformation. */ private final Rectangle2D.Double visBounds = new Rectangle2D.Double(); /** PortInst on tail end of this arc instance */ /*package*/final PortInst tailPortInst; /** PortInst on head end of this arc instance */ /*package*/final PortInst headPortInst; /** * Private constructor of ArcInst. * @param topology the Topology of the ArcInst. * @param d persistent data of ArcInst. * @param headPort the head end PortInst. * @param tailPort the tail end PortInst. */ public ArcInst(Topology topology, ImmutableArcInst d, PortInst headPort, PortInst tailPort) { super(topology.cell); this.topology = topology; // initialize this object assert parent == headPort.getNodeInst().getParent(); assert parent == tailPort.getNodeInst().getParent(); assert d.headNodeId == headPort.getNodeInst().getD().nodeId; assert d.tailNodeId == tailPort.getNodeInst().getD().nodeId; assert d.headPortId == headPort.getPortProto().getId(); assert d.tailPortId == tailPort.getPortProto().getId(); this.d = d; // create node/arc connections and place them properly tailPortInst = tailPort;// tailEnd = new TailConnection(this); headPortInst = headPort;// headEnd = new HeadConnection(this); } private Object writeReplace() { return new ArcInstKey(this); } private static class ArcInstKey extends EObjectInputStream.Key<ArcInst> { public ArcInstKey() {} private ArcInstKey(ArcInst ai) { super(ai); } @Override public void writeExternal(EObjectOutputStream out, ArcInst ai) throws IOException { if (ai.getDatabase() != out.getDatabase() || !ai.isLinked()) throw new NotSerializableException(ai + " not linked"); out.writeObject(ai.getParent()); out.writeInt(ai.getArcId()); } @Override public ArcInst readExternal(EObjectInputStream in) throws IOException, ClassNotFoundException { Cell cell = (Cell)in.readObject(); int arcId = in.readInt(); ArcInst ai = cell.getArcById(arcId); if (ai == null) throw new InvalidObjectException("ArcInst from " + cell); return ai; } } /****************************** CREATE, DELETE, MODIFY ******************************/ /** * Method to create a new ArcInst with appropriate defaults, connecting two PortInsts. * Since no coordinates are given, the ArcInst connects to the center of the PortInsts. * @param type the prototype of the new ArcInst. * @param head the head end PortInst. * @param tail the tail end PortInst. * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst makeInstance(ArcProto type, PortInst head, PortInst tail) { return newInstanceBase(type, type.getDefaultLambdaBaseWidth(), head, tail, null, null, null, 0, type.getDefaultConstraints()); } /** * Method to create a new ArcInst with appropriate defaults, connecting two PortInsts. * Since no coordinates are given, the ArcInst connects to the center of the PortInsts. * @param type the prototype of the new ArcInst. * @param baseWidth the base width of the new ArcInst. The width must be > 0. * @param head the head end PortInst. * @param tail the tail end PortInst. * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst makeInstanceBase(ArcProto type, double baseWidth, PortInst head, PortInst tail) { return newInstanceBase(type, baseWidth, head, tail, null, null, null, 0, type.getDefaultConstraints()); } /** * Method to create a new ArcInst with appropriate defaults, connecting two PortInsts at specified locations. * This is more general than the version that does not take coordinates. * @param type the prototype of the new ArcInst. * @param head the head end PortInst. * @param tail the tail end PortInst. * @param headPt the coordinate of the head end PortInst. * @param tailPt the coordinate of the tail end PortInst. * @param name the name of the new ArcInst * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst makeInstance(ArcProto type, PortInst head, PortInst tail, Point2D headPt, Point2D tailPt, String name) { return newInstanceBase(type, type.getDefaultLambdaBaseWidth(), head, tail, headPt, tailPt, name, 0, type.getDefaultConstraints()); } /** * Method to create a new ArcInst with appropriate defaults, connecting two PortInsts at specified locations. * This is more general than the version that does not take coordinates. * @param type the prototype of the new ArcInst. * @param baseWidth the base width of the new ArcInst. The width must be > 0. * @param head the head end PortInst. * @param tail the tail end PortInst. * @param headPt the coordinate of the head end PortInst. * @param tailPt the coordinate of the tail end PortInst. * @param name the name of the new ArcInst * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst makeInstanceBase(ArcProto type, double baseWidth, PortInst head, PortInst tail, Point2D headPt, Point2D tailPt, String name) { return newInstanceBase(type, baseWidth, head, tail, headPt, tailPt, name, 0, type.getDefaultConstraints()); } /** * Method to create a new ArcInst connecting two PortInsts. * Since no coordinates are given, the ArcInst connects to the center of the PortInsts. * @param type the prototype of the new ArcInst. * @param baseWidth the base width of the new ArcInst. The width must be > 0. * @param head the head end PortInst. * @param tail the tail end PortInst. * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst newInstanceBase(ArcProto type, double baseWidth, PortInst head, PortInst tail) { return newInstanceBase(type, baseWidth, head, tail, null, null, null, 0, ImmutableArcInst.DEFAULT_FLAGS); } /** * Method to create a new ArcInst connecting two PortInsts at specified locations. * This is more general than the version that does not take coordinates. * @param type the prototype of the new ArcInst. * @param baseWidth the base width of the new ArcInst. The width must be > 0. * @param head the head end PortInst. * @param tail the tail end PortInst. * @param headPt the coordinate of the head end PortInst. * @param tailPt the coordinate of the tail end PortInst. * @param name the name of the new ArcInst * @param defAngle default angle in case port points coincide * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst newInstanceBase(ArcProto type, double baseWidth, PortInst head, PortInst tail, Point2D headPt, Point2D tailPt, String name, int defAngle) { return newInstanceBase(type, baseWidth, head, tail, headPt, tailPt, name, defAngle, ImmutableArcInst.DEFAULT_FLAGS); } /** * Method to create a new ArcInst connecting two PortInsts at specified locations. * This is more general than the version that does not take coordinates. * @param type the prototype of the new ArcInst. * @param baseWidth the base width of the new ArcInst. The width must be > 0. * @param head the head end PortInst. * @param tail the tail end PortInst. * @param headPt the coordinate of the head end PortInst. * @param tailPt the coordinate of the tail end PortInst. * @param name the name of the new ArcInst * @param defAngle default angle in case port points coincide * @param flags flags of thew new ArcInst * @return the newly created ArcInst, or null if there is an error. */ public static ArcInst newInstanceBase(ArcProto type, double baseWidth, PortInst head, PortInst tail, Point2D headPt, Point2D tailPt, String name, int defAngle, int flags) {// if (type.isNotUsed())// {//// System.out.println("Cannot create arc instance of " + type + " because prototype is unused");//// return null;// } long gridExtendOverMin = DBMath.lambdaToGrid(0.5*baseWidth) - type.getGridBaseExtend();// if (gridFullWidth < type.getMaxLayerGridOffset())// gridFullWidth = type.getDefaultGridFullWidth(); // if points are null, create them as would newInstance EPoint headP; if (headPt == null) {// Rectangle2D headBounds = head.getBounds(); headP = head.getCenter(); //new EPoint(headBounds.getCenterX(), headBounds.getCenterY()); } else { headP = EPoint.snap(headPt); } EPoint tailP; if (tailPt == null) {// Rectangle2D tailBounds = tail.getBounds(); tailP = tail.getCenter(); // new EPoint(tailBounds.getCenterX(), tailBounds.getCenterY()); } else { tailP = EPoint.snap(tailPt); } // make sure points are valid Cell parent = head.getNodeInst().getParent(); Poly headPoly = head.getPoly(); if (!stillInPoly(headP, headPoly)) { System.out.println("Error in " + parent + ": head of " + type.getName() + " arc at (" + headP.getX() + "," + headP.getY() + ") does not fit in " + head + " which is centered at (" + headPoly.getCenterX() + "," + headPoly.getCenterY() + ")"); return null; } Poly tailPoly = tail.getPoly(); if (!stillInPoly(tailP, tailPoly)) { System.out.println("Error in " + parent + ": tail of " + type.getName() + " arc at (" + tailP.getX() + "," + tailP.getY() + ") does not fit in " + tail + " which is centered at (" + tailPoly.getCenterX() + "," + tailPoly.getCenterY() + ")"); return null; } return newInstance(parent, type, name, null, head, tail, headP, tailP, gridExtendOverMin, defAngle, flags); } /** * Method to create a new ArcInst connecting two PortInsts at specified locations. * This is more general than the version that does not take coordinates. * @param parent the parent Cell of this ArcInst * @param protoType the ArcProto of this ArcInst. * @param name the name of this ArcInst * @param nameDescriptor text descriptor of name of this ArcInst * @param headPort the head end PortInst. * @param tailPort the tail end PortInst.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -