/** * Checks, if a polyline trace with the input parameters can be inserted without clearance * violations */ public boolean check_polyline_trace( Polyline p_polyline, int p_layer, int p_pen_half_width, int[] p_net_no_arr, int p_clearance_class) { Trace tmp_trace = new PolylineTrace( p_polyline, p_layer, p_pen_half_width, p_net_no_arr, p_clearance_class, 0, 0, FixedState.UNFIXED, this); Set<Pin> contact_pins = tmp_trace.touching_pins_at_end_corners(); for (int i = 0; i < tmp_trace.tile_shape_count(); ++i) { if (!this.check_trace_shape( tmp_trace.get_tile_shape(i), p_layer, p_net_no_arr, p_clearance_class, contact_pins)) { return false; } } return true; }
/** * Checks, if p_item item is part of a cycle and remuve it together with its connection in this * case. */ public boolean remove_if_cycle(Trace p_trace) { if (!p_trace.is_on_the_board()) { return false; } if (!p_trace.is_cycle()) { return false; } // Remove tails at the endpoints after removing the cycle, // if there was no tail before. boolean[] tail_at_endpoint_before = null; Point[] end_corners = null; int curr_layer = p_trace.get_layer(); int[] curr_net_no_arr = p_trace.net_no_arr; end_corners = new Point[2]; end_corners[0] = p_trace.first_corner(); end_corners[1] = p_trace.last_corner(); tail_at_endpoint_before = new boolean[2]; for (int i = 0; i < 2; ++i) { Trace tail = get_trace_tail(end_corners[i], curr_layer, curr_net_no_arr); tail_at_endpoint_before[i] = (tail != null); } Set<Item> connection_items = p_trace.get_connection_items(); this.remove_items(connection_items, false); for (int i = 0; i < 2; ++i) { if (!tail_at_endpoint_before[i]) { Trace tail = get_trace_tail(end_corners[i], curr_layer, curr_net_no_arr); if (tail != null) { remove_items(tail.get_connection_items(), false); } } } return true; }
/** * Looks for traces of the input net on the input layer, so that p_location is on the trace * polygon, and splits these traces. Returns false, if no trace was split. */ public boolean split_traces(Point p_location, int p_layer, int p_net_no) { ItemSelectionFilter filter = new ItemSelectionFilter(ItemSelectionFilter.SelectableChoices.TRACES); Collection<Item> picked_items = this.pick_items(p_location, p_layer, filter); IntOctagon location_shape = TileShape.get_instance(p_location).bounding_octagon(); boolean trace_split = false; for (Item curr_item : picked_items) { Trace curr_trace = (Trace) curr_item; if (curr_trace.contains_net(p_net_no)) { Collection<PolylineTrace> split_pieces = curr_trace.split(location_shape); if (split_pieces.size() != 1) { trace_split = true; } } } return trace_split; }
/** * Maybe trace of type turret without net in Mentor design. Try to assig the net by calculating * the overlaps. */ private void try_correct_net(Item p_item) { if (!(p_item instanceof Trace)) { return; } Trace curr_trace = (Trace) p_item; java.util.Set<Item> contacts = curr_trace.get_normal_contacts(curr_trace.first_corner(), true); contacts.addAll(curr_trace.get_normal_contacts(curr_trace.last_corner(), true)); int corrected_net_no = 0; for (Item curr_contact : contacts) { if (curr_contact.net_count() == 1) { corrected_net_no = curr_contact.get_net_no(0); break; } } if (corrected_net_no != 0) { p_item.assign_net_no(corrected_net_no); } }
/** * Looks if at the input position ends a trace with the input net number, which has no normal * contact at that position. Returns null, if no tail is found. */ public Trace get_trace_tail(Point p_location, int p_layer, int[] p_net_no_arr) { TileShape point_shape = TileShape.get_instance(p_location); Collection<SearchTreeObject> found_items = overlapping_objects(point_shape, p_layer); Iterator<SearchTreeObject> it = found_items.iterator(); while (it.hasNext()) { SearchTreeObject curr_ob = it.next(); if (curr_ob instanceof Trace) { Trace curr_trace = (Trace) curr_ob; if (!curr_trace.nets_equal(p_net_no_arr)) { continue; } if (curr_trace.first_corner().equals(p_location)) { Collection<Item> contacts = curr_trace.get_start_contacts(); if (contacts.size() == 0) { return curr_trace; } } if (curr_trace.last_corner().equals(p_location)) { Collection<Item> contacts = curr_trace.get_end_contacts(); if (contacts.size() == 0) { return curr_trace; } } } } return null; }
Point normal_contact_point(Trace p_other) { if (this.layer != p_other.layer) { return null; } boolean contact_at_first_corner = this.first_corner().equals(p_other.first_corner()) || this.first_corner().equals(p_other.last_corner()); boolean contact_at_last_corner = this.last_corner().equals(p_other.first_corner()) || this.last_corner().equals(p_other.last_corner()); Point result; if (!(contact_at_first_corner || contact_at_last_corner) || contact_at_first_corner && contact_at_last_corner) { // no contact point or more than 1 contact point result = null; } else if (contact_at_first_corner) { result = this.first_corner(); } else // contact at last corner { result = this.last_corner(); } return result; }
/** * Get a list of all items having a connection point at p_point on the layer of this trace. If * p_ignore_net is false, only contacts to items sharing a net with this trace are calculated. * This is the normal case. * * @param p_point a {@link geometry.planar.Point} object. * @param p_ignore_net a boolean. * @return a {@link java.util.Set} object. */ public Set<Item> get_normal_contacts(Point p_point, boolean p_ignore_net) { if (p_point == null || !(p_point.equals(this.first_corner()) || p_point.equals(this.last_corner()))) { return new TreeSet<Item>(); } TileShape search_shape = TileShape.get_instance(p_point); Set<SearchTreeObject> overlaps = board.overlapping_objects(search_shape, this.layer); Set<Item> result = new TreeSet<Item>(); for (SearchTreeObject curr_ob : overlaps) { if (!(curr_ob instanceof Item)) { continue; } Item curr_item = (Item) curr_ob; if (curr_item != this && curr_item.shares_layer(this) && (p_ignore_net || curr_item.shares_net(this))) { if (curr_item instanceof Trace) { Trace curr_trace = (Trace) curr_item; if (p_point.equals(curr_trace.first_corner()) || p_point.equals(curr_trace.last_corner())) { result.add(curr_item); } } else if (curr_item instanceof DrillItem) { DrillItem curr_drill_item = (DrillItem) curr_item; if (p_point.equals(curr_drill_item.get_center())) { result.add(curr_item); } } else if (curr_item instanceof ConductionArea) { ConductionArea curr_area = (ConductionArea) curr_item; if (curr_area.get_area().contains(p_point)) { result.add(curr_item); } } } } return result; }
private static void write_wire_scope(WriteScopeParameter p_par, Trace p_wire) throws java.io.IOException { if (!(p_wire instanceof PolylineTrace)) { System.out.println("Wiring.write_wire_scope: trace type not yet implemented"); return; } PolylineTrace curr_wire = (PolylineTrace) p_wire; int layer_no = curr_wire.get_layer(); board.Layer board_layer = p_par.board.layer_structure.arr[layer_no]; Layer curr_layer = new Layer(board_layer.name, layer_no, board_layer.is_signal); double wire_width = p_par.coordinate_transform.board_to_dsn(2 * curr_wire.get_half_width()); rules.Net wire_net = null; if (curr_wire.net_count() > 0) { wire_net = p_par.board.rules.nets.get(curr_wire.get_net_no(0)); } if (wire_net == null) { System.out.println("Wiring.write_wire_scope: net not found"); return; } p_par.file.start_scope(); p_par.file.write("wire"); if (p_par.compat_mode) { Point[] corner_arr = curr_wire.polyline().corner_arr(); FloatPoint[] float_corner_arr = new FloatPoint[corner_arr.length]; for (int i = 0; i < corner_arr.length; ++i) { float_corner_arr[i] = corner_arr[i].to_float(); } double[] coors = p_par.coordinate_transform.board_to_dsn(float_corner_arr); PolygonPath curr_path = new PolygonPath(curr_layer, wire_width, coors); curr_path.write_scope(p_par.file, p_par.identifier_type); } else { double[] coors = p_par.coordinate_transform.board_to_dsn(curr_wire.polyline().arr); PolylinePath curr_path = new PolylinePath(curr_layer, wire_width, coors); curr_path.write_scope(p_par.file, p_par.identifier_type); } write_net(wire_net, p_par.file, p_par.identifier_type); Rule.write_item_clearance_class( p_par.board.rules.clearance_matrix.get_name(p_wire.clearance_class_no()), p_par.file, p_par.identifier_type); write_fixed_state(p_par.file, curr_wire.get_fixed_state()); p_par.file.end_scope(); }