/*
* Copyright (C) 2014 Alfons Wirtz
* website www.freerouting.net
*
* This program 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.
*
* This program 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 at <http://www.gnu.org/licenses/>
* for more details.
*
* NetClass.java
*
* Created on 7. April 2005, 06:08
*/
package rules;
/**
* Describes routing rules for individual nets.
*
* @author Alfons Wirtz
*/
public class NetClass implements java.io.Serializable, board.ObjectInfoPanel.Printable
{
/** Creates a new instance of NetClass */
public NetClass(String p_name, board.LayerStructure p_layer_structure, ClearanceMatrix p_clearance_matrix)
{
this.name = p_name;
this.board_layer_structure = p_layer_structure;
this.clearance_matrix = p_clearance_matrix;
this.trace_half_width_arr = new int[p_layer_structure.arr.length];
this.active_routing_layer_arr = new boolean[p_layer_structure.arr.length];
for (int i = 0; i < p_layer_structure.arr.length; ++i)
{
this.active_routing_layer_arr[i] = p_layer_structure.arr[i].is_signal;
}
}
public String toString()
{
return this.name;
}
/**
* Changes the name of this net class.
*/
public void set_name(String p_name)
{
this.name = p_name;
}
/**
* Gets the name of this net class.
*/
public String get_name()
{
return this.name;
}
/**
* Sets the trace half width used for routing to p_value on all layers.
*/
public void set_trace_half_width(int p_value)
{
java.util.Arrays.fill(trace_half_width_arr, p_value);
}
/**
* Sets the trace half width used for routing to p_value on all inner layers.
*/
public void set_trace_half_width_on_inner(int p_value)
{
for (int i = 1; i < trace_half_width_arr.length - 1; ++i)
{
trace_half_width_arr[i] = p_value;
}
}
/**
* Sets the trace half width used for routing to p_value on the input layer.
*/
public void set_trace_half_width(int p_layer, int p_value)
{
trace_half_width_arr[p_layer] = p_value;
}
public int layer_count()
{
return trace_half_width_arr.length;
}
/**
* Gets the trace half width used for routing on the input layer.
*/
public int get_trace_half_width(int p_layer)
{
if (p_layer < 0 || p_layer >= trace_half_width_arr.length)
{
System.out.println(" NetClass.get_trace_half_width: p_layer out of range");
return 0;
}
return trace_half_width_arr[p_layer];
}
/**
* Sets the clearance class used for routing traces with this net rclass.
*/
public void set_trace_clearance_class(int p_clearance_class_no)
{
this.trace_clearance_class = p_clearance_class_no;
}
/**
* Gets the clearance class used for routing traces with this net class.
*/
public int get_trace_clearance_class()
{
return this.trace_clearance_class;
}
/**
* Sets the via rule of this net class.
*/
public void set_via_rule(ViaRule p_via_rule)
{
this.via_rule = p_via_rule;
}
/**
* Gets the via rule of this net rule.
*/
public ViaRule get_via_rule()
{
return this.via_rule;
}
/**
* Sets, if traces and vias of this net class can be pushed.
*/
public void set_shove_fixed(boolean p_value)
{
this.shove_fixed = p_value;
}
/**
* Returns, if traces and vias of this net class can be pushed.
*/
public boolean is_shove_fixed()
{
return this.shove_fixed;
}
/**
* Sets, if traces of this nets class are pulled tight.
*/
public void set_pull_tight(boolean p_value)
{
this.pull_tight = p_value;
}
/**
* Returns, if traces of this nets class are pulled tight.
*/
public boolean get_pull_tight()
{
return this.pull_tight;
}
/**
* Sets, if the cycle remove algorithm ignores cycles, where conduction areas are involved
*/
public void set_ignore_cycles_with_areas(boolean p_value)
{
this.ignore_cycles_with_areas = p_value;
}
/**
* Returns, if the cycle remove algorithm ignores cycles, where conduction areas are involved
*/
public boolean get_ignore_cycles_with_areas()
{
return this.ignore_cycles_with_areas;
}
/**
* Returns the minimum trace length of this net class.
* If the result is <= 0, there is no minimal trace length restriction.
*/
public double get_minimum_trace_length()
{
return minimum_trace_length;
}
/**
* Sets the minimum trace length of this net class to p_value.
* If p_value is <= 0, there is no minimal trace length restriction.
*/
public void set_minimum_trace_length(double p_value)
{
minimum_trace_length = p_value;
}
/**
* Returns the maximum trace length of this net class.
* If the result is <= 0, there is no maximal trace length restriction.
*/
public double get_maximum_trace_length()
{
return maximum_trace_length;
}
/**
* Sets the maximum trace length of this net class to p_value.
* If p_value is <= 0, there is no maximal trace length restriction.
*/
public void set_maximum_trace_length(double p_value)
{
maximum_trace_length = p_value;
}
/**
* Returns if the layer with index p_layer_no is active for routing
*/
public boolean is_active_routing_layer(int p_layer_no)
{
if (p_layer_no < 0 || p_layer_no >= this.active_routing_layer_arr.length)
{
return false;
}
return this.active_routing_layer_arr[p_layer_no];
}
/**
* Sets the layer with index p_layer_no to p_active.
*/
public void set_active_routing_layer(int p_layer_no, boolean p_active)
{
if (p_layer_no < 0 || p_layer_no >= this.active_routing_layer_arr.length)
{
return;
}
this.active_routing_layer_arr[p_layer_no] = p_active;
}
/**
* Activates or deactivates all layers for routing
*/
public void set_all_layers_active(boolean p_value)
{
java.util.Arrays.fill(this.active_routing_layer_arr, p_value);
}
/**
* Activates or deactivates all inner layers for routing
*/
public void set_all_inner_layers_active(boolean p_value)
{
for (int i = 1; i < trace_half_width_arr.length - 1; ++i)
{
active_routing_layer_arr[i] = p_value;
}
}
public void print_info(board.ObjectInfoPanel p_window, java.util.Locale p_locale)
{
java.util.ResourceBundle resources =
java.util.ResourceBundle.getBundle("board.resources.ObjectInfoPanel", p_locale);
p_window.append_bold(resources.getString("net_class_2") + " ");
p_window.append_bold(this.name);
p_window.append_bold(":");
p_window.append(" " + resources.getString("trace_clearance_class") + " ");
String cl_name = clearance_matrix.get_name(this.trace_clearance_class);
p_window.append(cl_name, resources.getString("trace_clearance_class_2"), clearance_matrix.get_row(this.trace_clearance_class));
if (this.shove_fixed)
{
p_window.append(", " + resources.getString("shove_fixed"));
}
p_window.append(", " + resources.getString("via_rule") + " ");
p_window.append(via_rule.name, resources.getString("via_rule_2"), via_rule);
if (trace_width_is_layer_dependent())
{
for (int i = 0; i < trace_half_width_arr.length; ++i)
{
p_window.newline();
p_window.indent();
p_window.append(resources.getString("trace_width") + " ");
p_window.append(2 * trace_half_width_arr[i]);
p_window.append(" " + resources.getString("on_layer") + " ");
p_window.append(this.board_layer_structure.arr[i].name);
}
}
else
{
p_window.append(", " + resources.getString("trace_width") + " ");
p_window.append(2 * trace_half_width_arr[0]);
}
p_window.newline();
}
/**
* Returns true, if the trace width of this class is not equal on all layers. */
public boolean trace_width_is_layer_dependent()
{
int compare_value = trace_half_width_arr[0];
for (int i = 1; i < trace_half_width_arr.length; ++i)
{
if (this.board_layer_structure.arr[i].is_signal)
{
if (trace_half_width_arr[i] != compare_value)
{
return true;
}
}
}
return false;
}
/**
* Returns true, if the trace width of this class is not equal on all inner layers.
*/
public boolean trace_width_is_inner_layer_dependent()
{
if (trace_half_width_arr.length <= 3)
{
return false;
}
int first_inner_layer_no = 1;
while (!this.board_layer_structure.arr[first_inner_layer_no].is_signal)
{
++first_inner_layer_no;
}
if (first_inner_layer_no >= trace_half_width_arr.length - 1)
{
return false;
}
int compare_width = trace_half_width_arr[first_inner_layer_no];
for (int i = first_inner_layer_no + 1; i < trace_half_width_arr.length - 1; ++i)
{
if (this.board_layer_structure.arr[i].is_signal)
{
if (trace_half_width_arr[i] != compare_width)
{
return true;
}
}
}
return false;
}
private String name;
private ViaRule via_rule;
private int trace_clearance_class;
private int[] trace_half_width_arr;
private boolean[] active_routing_layer_arr;
/** if null, all signal layers may be used for routing */
private boolean shove_fixed = false;
private boolean pull_tight = true;
private boolean ignore_cycles_with_areas = false;
private double minimum_trace_length = 0;
private double maximum_trace_length = 0;
private final ClearanceMatrix clearance_matrix;
private final board.LayerStructure board_layer_structure;
/**
* The clearance classes of the item types, if this net class comes from a class in a Speccctra dsn-file
* Should evtl be moved to designformats.specctra.NetClass and used only when reading a dsn-file.
*/
public DefaultItemClearanceClasses default_item_clearance_classes = new DefaultItemClearanceClasses();
}