⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interactiverouter.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        VerticalRoute vroute = VerticalRoute.newRoute(startPort, endPort);        if (!vroute.isSpecificationSucceeded()) return new Route();        // arc width of arcs that will connect to startObj, endObj will determine        // valid attachment points of arcs        ArcProto startArc = vroute.getStartArc();        ArcProto endArc = vroute.getEndArc();        double startArcWidth = getArcWidthToUse(startObj, startArc);        double endArcWidth = (endObj == null) ? startArcWidth : getArcWidthToUse(endObj, endArc);        // if extension not supressed, use defaults from arcs        if (extendArcHead) extendArcHead = startArc.isExtended() || endArc.isExtended();        if (extendArcTail) extendArcTail = startArc.isExtended() || endArc.isExtended();        // get valid connecting sites for start and end objects based on the objects        // themselves, the point the user clicked, and the width of the wire that will        // attach to each        Poly startPoly = getConnectingSite(startObj, clicked, startArcWidth);        Poly endPoly = getConnectingSite(endObj, clicked, endArcWidth);        // Now we can figure out where on the start and end objects the connecting        // arc(s) should connect        Point2D startPoint = new Point2D.Double(0, 0);        Point2D endPoint = new Point2D.Double(0,0);        getConnectingPoints(startObj, endObj, clicked, startPoint, endPoint, startPoly, endPoly, startArc, endArc);        PortInst existingStartPort = null;        PortInst existingEndPort = null;        // favor contact cuts on arcs        boolean contactsOnEndObject = true;        // plan start of route        if (startObj instanceof PortInst) {            // portinst: just wrap in RouteElement            existingStartPort = (PortInst)startObj;            startRE = RouteElementPort.existingPortInst(existingStartPort, startPoly);        }        if (startObj instanceof ArcInst) {            // arc: figure out where on arc to start            startRE = findArcConnectingPoint(route, (ArcInst)startObj, startPoint, stayInside);            contactsOnEndObject = false;        }        if (startRE == null) {            if (startObj != badStartObject)                System.out.println("  Can't route from "+startObj+", no ports");            badStartObject = startObj;            return route;        }        // plan end of route        if (endObj != null) {            // we have somewhere to route to            if (endObj instanceof PortInst) {                // portinst: just wrap in RouteElement                existingEndPort = (PortInst)endObj;                endRE = RouteElementPort.existingPortInst(existingEndPort, endPoly);            }            if (endObj instanceof ArcInst) {                // arc: figure out where on arc to end                // use startRE location when possible if connecting to arc                endRE = findArcConnectingPoint(route, (ArcInst)endObj, endPoint, stayInside);                contactsOnEndObject = true;            }            if (endRE == null) {                if (endObj != badEndObject)                    System.out.println("  Can't route to "+endObj+", no ports");                badEndObject = endObj;                endObj = null;            }        }        if (endObj == null) {            // nowhere to route to, must make new pin to route to            // first we need to determine what pin to make based on            // start object            ArcProto useArc = null;            if (startObj instanceof PortInst) {                PortInst startPi = (PortInst)startObj;                useArc = getArcToUse(startPi.getPortProto(), null);            }            if (startObj instanceof ArcInst) {                ArcInst startAi = (ArcInst)startObj;                useArc = startAi.getProto();            }            // make new pin to route to            PrimitiveNode pn = useArc.findOverridablePinProto();            SizeOffset so = pn.getProtoSizeOffset();            endRE = RouteElementPort.newNode(cell, pn, pn.getPort(0), endPoint,                    pn.getDefWidth()-so.getHighXOffset()-so.getLowXOffset(),                    pn.getDefHeight()-so.getHighYOffset()-so.getLowYOffset());        }        // favor contact on bisected arc        if (startRE.isBisectArcPin()) contactsOnEndObject = false;        if (endRE != null && endRE.isBisectArcPin()) contactsOnEndObject = true;        // special check: if both are existing port insts and are same port, do nothing        if ((existingEndPort != null) && (existingEndPort == existingStartPort)) return new Route();        // add startRE and endRE to route        route.add(startRE);        route.setStart(startRE);        route.setEnd(startRE);        //route.add(endRE); route.setEnd(endRE);        // Tell Router to route between startRE and endRE        if (planRoute(route, cell, endRE, startPoint, endPoint, clicked, stayInside, vroute, contactsOnEndObject,                extendArcHead, extendArcTail, contactArea)) {            return route;        }        return new Route();             // error, return empty route    }    // -------------------- Internal Router Utility Methods --------------------    /**     * If routeObj is a NodeInst, first thing we do is get the nearest PortInst     * to where the user clicked, and use that instead.     * @param routeObj the route object (possibly a NodeInst).     * @param clicked where the user clicked     * @return the PortInst on the NodeInst closest to where the user clicked,     * or just the routeObj back if it is not a NodeInst.     */    protected static ElectricObject filterRouteObject(ElectricObject routeObj, Point2D clicked) {        if (routeObj instanceof NodeInst) {            return ((NodeInst)routeObj).findClosestPortInst(clicked);        }        if (routeObj instanceof Export) {            Export exp = (Export)routeObj;            return exp.getOriginalPort();        }        return routeObj;    }    /**     * Get the PortProto associated with routeObj (it should be either     * a ArcInst or a PortInst, otherwise this will return null).     * @param routeObj the route object     * @return the PortProto for this route object     */    protected static PortProto getRoutePort(ElectricObject routeObj) {        assert(!(routeObj instanceof NodeInst));        if (routeObj instanceof ArcInst) {            ArcInst ai = (ArcInst)routeObj;            PrimitiveNode pn = ai.getProto().findOverridablePinProto();            return pn.getPort(0);        }        if (routeObj instanceof PortInst) {            PortInst pi = (PortInst)routeObj;            return pi.getPortProto();        }        return null;    }    protected static double getArcWidthToUse(ElectricObject routeObj, ArcProto ap) {        double width = -1;        if (routeObj instanceof ArcInst) {            ArcInst ai = (ArcInst)routeObj;            if (ai.getProto() == ap)                return ai.getLambdaBaseWidth();        }        if (routeObj instanceof PortInst) {            width = Router.getArcWidthToUse((PortInst)routeObj, ap);        }        return width;    }    /**     * Get the connecting points for the start and end objects of the route. This fills in     * the two Point2D's startPoint and endPoint. These will be the end points of an arc that     * connects to either startObj or endObj.     * @param startObj the start route object     * @param endObj the end route object     * @param clicked where the user clicked     * @param startPoint point inside startPoly on startObj to connect arc to     * @param endPoint point inside endPoly on endObj to connect arc to     * @param startPoly valid port site on startObj     * @param endPoly valid port site on endObj     */    protected static void getConnectingPoints(ElectricObject startObj, ElectricObject endObj, Point2D clicked,                                              Point2D startPoint, Point2D endPoint, Poly startPoly, Poly endPoly,                                              ArcProto startArc, ArcProto endArc) {/*        Point2D[] points = startPoly.getPoints();        System.out.print("StartPoly: ");        for (int i=0; i<points.length; i++) {            System.out.print(points[i]+", ");        }        System.out.println("");        if (endPoly != null) {            points = endPoly.getPoints();            System.out.print("EndPoly: ");            for (int i=0; i<points.length; i++) {                System.out.print(points[i]+", ");            }            System.out.println("");        }*/        if ((startPoly.getBox() == null && startPoly.getPoints().length != 2) ||            (endPoly != null && endPoly.getBox() == null && endPoly.getPoints().length != 2)) {            // special case: one of the polys is not a rectangle            startPoint.setLocation(startPoly.closestPoint(clicked));            if (endPoly == null) {                endPoint.setLocation(getClosestOrthogonalPoint(startPoint, clicked));            } else {                endPoint.setLocation(endPoly.closestPoint(clicked));            }            return;        }        // just go by bounds for now        Rectangle2D startBounds = startPoly.getBounds2D();        // default is center point        startPoint.setLocation(startBounds.getCenterX(), startBounds.getCenterY());        if (startObj instanceof ArcInst) {            double x, y;            // if nothing to connect to, clicked will determine connecting point on startPoly            // endPoint will be location of new pin            x = getClosestValue(startBounds.getMinX(), startBounds.getMaxX(), clicked.getX());            y = getClosestValue(startBounds.getMinY(), startBounds.getMaxY(), clicked.getY());            startPoint.setLocation(x, y);        }        if (endPoly == null) {            // if arc, find place to connect to. Otherwise use the center point (default)            int angleIncrement = endArc.getAngleIncrement();            endPoint.setLocation(getClosestAngledPoint(startPoint, clicked, angleIncrement));            //endPoint.setLocation(getClosestOrthogonalPoint(startPoint, clicked));            // however, if this is an Artwork technology, just put end point at mouse            if (startArc.getTechnology() == Artwork.tech())                endPoint.setLocation(clicked);            return;        }        Rectangle2D endBounds = endPoly.getBounds2D();        endPoint.setLocation(endBounds.getCenterX(), endBounds.getCenterY());        if (endObj instanceof ArcInst) {            double x, y;            // if nothing to connect to, clicked will determine connecting point on startPoly            // endPoint will be location of new pin            x = getClosestValue(endBounds.getMinX(), endBounds.getMaxX(), clicked.getX());            y = getClosestValue(endBounds.getMinY(), endBounds.getMaxY(), clicked.getY());            endPoint.setLocation(x, y);        }        // if bounds share x-space, use closest x within that space to clicked point        double lowerBoundX = Math.max(startBounds.getMinX(), endBounds.getMinX());        double upperBoundX = Math.min(startBounds.getMaxX(), endBounds.getMaxX());        if (lowerBoundX <= upperBoundX) {            double x = getClosestValue(lowerBoundX, upperBoundX, clicked.getX());            startPoint.setLocation(x, startPoint.getY());            endPoint.setLocation(x, endPoint.getY());        } else {            // otherwise, use closest point in bounds to the other port            // see which one is higher in X...they don't overlap, so any X coord in bounds is comparable            if (startBounds.getMinX() > endBounds.getMaxX()) {                startPoint.setLocation(startBounds.getMinX(), startPoint.getY());                endPoint.setLocation(endBounds.getMaxX(), endPoint.getY());            } else {                startPoint.setLocation(startBounds.getMaxX(), startPoint.getY());                endPoint.setLocation(endBounds.getMinX(), endPoint.getY());            }        }        // if bounds share y-space, use closest y within that space to clicked point        double lowerBoundY = Math.max(startBounds.getMinY(), endBounds.getMinY());        double upperBoundY = Math.min(startBounds.getMaxY(), endBounds.getMaxY());        if (lowerBoundY <= upperBoundY) {            double y = getClosestValue(lowerBoundY, upperBoundY, clicked.getY());            startPoint.setLocation(startPoint.getX(), y);            endPoint.setLocation(endPoint.getX(), y);        } else {            // otherwise, use closest point in bounds to the other port            // see which one is higher in Y...they don't overlap, so any Y coord in bounds is comparable            if (startBounds.getMinY() > endBounds.getMaxY()) {                startPoint.setLocation(startPoint.getX(), startBounds.getMinY());                endPoint.setLocation(endPoint.getX(), endBounds.getMaxY());            } else {                startPoint.setLocation(startPoint.getX(), startBounds.getMaxY());                endPoint.setLocation(endPoint.getX(), endBounds.getMinY());            }        }    }    /**     * Get the connecting site of the electric object.     * <ul>     * <li>For NodeInsts, this is the nearest portinst to "clicked", which is then subject to:     * <li>For PortInsts, this is the nearest site of a multisite port, or just the entire port     * <li>For ArcInsts, this is a poly composed of the head location and the tail location     * </ul>     * See NodeInst.getShapeOfPort() for more details.     * @param obj the object to get a connection site for     * @param clicked used to find the nearest portinst on a nodeinst, and nearest     * site on a multisite port     * @param arcWidth contacts port sites are restricted by the size of arcs connecting     * to them, such that the arc width does extend beyond the contact edges.     * @return a poly describing where something can connect to     */    protected static Poly getConnectingSite(ElectricObject obj, Point2D clicked, double arcWidth) {        assert(clicked != null);        if (obj instanceof NodeInst) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -