279 lines
9.2 KiB
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;
|
|
}
|