freerouting/src/main/java/eu/mihosoft/freerouting/board/Via.java

279 lines
9.2 KiB
Java

/*
* 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.
*
* Via.java
*
* Created on 5. Juni 2003, 10:36
*/
package eu.mihosoft.freerouting.board;
import java.util.Collection;
import java.util.Iterator;
import eu.mihosoft.freerouting.geometry.planar.Point;
import eu.mihosoft.freerouting.geometry.planar.IntPoint;
import eu.mihosoft.freerouting.geometry.planar.TileShape;
import eu.mihosoft.freerouting.geometry.planar.Shape;
import eu.mihosoft.freerouting.geometry.planar.Vector;
import eu.mihosoft.freerouting.library.Padstack;
/**
* Class describing the functionality of an electrical Item on the eu.mihosoft.freerouting.board,
* which may have a shape on several layer, whose geometry is described by a
* padstack.
*
* @author Alfons Wirtz
*/
public class Via extends DrillItem implements java.io.Serializable
{
/** Creates a new instance of Via with the input parameters*/
public Via(Padstack p_padstack, Point p_center, int[] p_net_no_arr, int p_clearance_type, int p_id_no,
int p_group_no, FixedState p_fixed_state, boolean p_attach_allowed, BasicBoard p_board)
{
super(p_center, p_net_no_arr, p_clearance_type, p_id_no, p_group_no, p_fixed_state, p_board);
this.padstack = p_padstack;
this.attach_allowed = p_attach_allowed;
}
public Item copy(int p_id_no)
{
return new Via(padstack, get_center(), net_no_arr, clearance_class_no(), p_id_no, get_component_no(),
get_fixed_state(), attach_allowed, board);
}
public Shape get_shape(int p_index)
{
if (padstack == null)
{
System.out.println("Via.get_shape: padstack is null");
return null;
}
if (this.precalculated_shapes == null)
{
this.precalculated_shapes = new Shape[padstack.to_layer() - padstack.from_layer() + 1];
for (int i = 0; i < this.precalculated_shapes.length; ++i)
{
int padstack_layer = i + this.first_layer();
Vector translate_vector = get_center().difference_by(Point.ZERO);
Shape curr_shape = padstack.get_shape(padstack_layer);
if (curr_shape == null)
{
this.precalculated_shapes[i] = null;
}
else
{
this.precalculated_shapes[i] = (Shape) curr_shape.translate_by(translate_vector);
}
}
}
return this.precalculated_shapes[p_index];
}
public Padstack get_padstack()
{
return padstack;
}
public void set_padstack(Padstack p_padstack)
{
padstack = p_padstack;
}
public boolean is_route()
{
return !is_user_fixed() && this.net_count() > 0;
}
public boolean is_obstacle(Item p_other)
{
if (p_other == this || p_other instanceof ComponentObstacleArea)
{
return false;
}
if ((p_other instanceof ConductionArea) && !((ConductionArea) p_other).get_is_obstacle())
{
return false;
}
if (!p_other.shares_net(this))
{
return true;
}
if (p_other instanceof Trace)
{
return false;
}
if (this.attach_allowed && p_other instanceof Pin && ((Pin) p_other).drill_allowed())
{
return false;
}
return true;
}
/**
* Checks, if the Via has contacts on at most 1 layer.
*/
public boolean is_tail()
{
Collection<Item> contact_list = this.get_normal_contacts();
if (contact_list.size() <= 1)
{
return true;
}
Iterator<Item> it = contact_list.iterator();
Item curr_contact_item = it.next();
int first_contact_first_layer = curr_contact_item.first_layer();
int first_contact_last_layer = curr_contact_item.last_layer();
while (it.hasNext())
{
curr_contact_item = it.next();
if (curr_contact_item.first_layer() != first_contact_first_layer || curr_contact_item.last_layer() != first_contact_last_layer)
{
return false;
}
}
return true;
}
public void change_placement_side(IntPoint p_pole)
{
if (this.board == null)
{
return;
}
Padstack new_padstack = this.board.library.get_mirrored_via_padstack(this.padstack);
if (new_padstack == null)
{
return;
}
this.padstack = new_padstack;
super.change_placement_side(p_pole);
clear_derived_data();
}
public eu.mihosoft.freerouting.autoroute.ExpansionDrill get_autoroute_drill_info(ShapeSearchTree p_autoroute_tree)
{
if (this.autoroute_drill_info == null)
{
eu.mihosoft.freerouting.autoroute.ItemAutorouteInfo via_autoroute_info = this.get_autoroute_info();
TileShape curr_drill_shape = TileShape.get_instance(this.get_center());
this.autoroute_drill_info =
new eu.mihosoft.freerouting.autoroute.ExpansionDrill(curr_drill_shape, this.get_center(), this.first_layer(), this.last_layer());
int via_layer_count = this.last_layer() - this.first_layer() + 1;
for (int i = 0; i < via_layer_count; ++i)
{
this.autoroute_drill_info.room_arr[i] = via_autoroute_info.get_expansion_room(i, p_autoroute_tree);
}
}
return this.autoroute_drill_info;
}
public void clear_derived_data()
{
super.clear_derived_data();
this.precalculated_shapes = null;
this.autoroute_drill_info = null;
}
public void clear_autoroute_info()
{
super.clear_autoroute_info();
this.autoroute_drill_info = null;
}
public boolean is_selected_by_filter(ItemSelectionFilter p_filter)
{
if (!this.is_selected_by_fixed_filter(p_filter))
{
return false;
}
return p_filter.is_selected(ItemSelectionFilter.SelectableChoices.VIAS);
}
public java.awt.Color[] get_draw_colors(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context)
{
java.awt.Color[] result;
if (this.net_count() == 0)
{
// display unconnected vias as obstacles
result = p_graphics_context.get_obstacle_colors();
}
else if (this.first_layer() >= this.last_layer())
{
// display vias with only one layer as pins
result = p_graphics_context.get_pin_colors();
}
else
{
result = p_graphics_context.get_via_colors(this.is_user_fixed());
}
return result;
}
public double get_draw_intensity(eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context)
{
double result;
if (this.net_count() == 0)
{
// display unconnected vias as obstacles
result = p_graphics_context.get_obstacle_color_intensity();
}
else if (this.first_layer() >= this.last_layer())
{
// display vias with only one layer as pins
result = p_graphics_context.get_pin_color_intensity();
}
else
{
result = p_graphics_context.get_via_color_intensity();
}
return result;
}
public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale)
{
java.util.ResourceBundle resources =
java.util.ResourceBundle.getBundle("eu.mihosoft.freerouting.board.resources.ObjectInfoPanel", p_locale);
p_window.append_bold(resources.getString("via"));
p_window.append(" " + resources.getString("at"));
p_window.append(this.get_center().to_float());
p_window.append(", " + resources.getString("padstack"));
p_window.append(padstack.name, resources.getString("padstack_info"), padstack);
this.print_connectable_item_info(p_window, p_locale);
p_window.newline();
}
public boolean write(java.io.ObjectOutputStream p_stream)
{
try
{
p_stream.writeObject(this);
} catch (java.io.IOException e)
{
return false;
}
return true;
}
private Padstack padstack;
/** True, if coppersharing of this via with smd pins of the same net is allowed. */
public final boolean attach_allowed;
transient private Shape[] precalculated_shapes = null;
/** Temporary data used in the eu.mihosoft.freerouting.autoroute algorithm. */
transient private eu.mihosoft.freerouting.autoroute.ExpansionDrill autoroute_drill_info = null;
}