freerouting/src/main/java/eu/mihosoft/freerouting/autoroute/CompleteFreeSpaceExpansionR...

268 lines
8.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.
*
* CompleteFreeSpaceExpansionRoom.java
*
* Created on 10. Februar 2004, 10:12
*/
package eu.mihosoft.freerouting.autoroute;
import eu.mihosoft.freerouting.geometry.planar.TileShape;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import eu.mihosoft.freerouting.datastructures.ShapeTree;
import eu.mihosoft.freerouting.board.SearchTreeObject;
import eu.mihosoft.freerouting.board.ShapeSearchTree;
import eu.mihosoft.freerouting.board.Connectable;
import eu.mihosoft.freerouting.board.Item;
/**
* An expansion room, whose shape is completely calculated,
* so that it can be stored in a shape tree.
*
* @author Alfons Wirtz
*/
public class CompleteFreeSpaceExpansionRoom extends FreeSpaceExpansionRoom implements CompleteExpansionRoom, SearchTreeObject
{
/**
* Creates a new instance of CompleteFreeSpaceExpansionRoom
*/
public CompleteFreeSpaceExpansionRoom(TileShape p_shape, int p_layer, int p_id_no)
{
super(p_shape, p_layer);
target_doors = new LinkedList<TargetItemExpansionDoor>();
id_no = p_id_no;
}
public void set_search_tree_entries(ShapeTree.Leaf [] p_entries, ShapeTree p_tree)
{
tree_entries = p_entries;
}
public int compareTo(Object p_other)
{
int result;
if (p_other instanceof FreeSpaceExpansionRoom)
{
result = ((CompleteFreeSpaceExpansionRoom) p_other).id_no - this.id_no;
}
else
{
result = -1;
}
return result;
}
/**
* Removes the tree entries of this roomm from p_shape_tree.
*/
public void remove_from_tree(ShapeTree p_shape_tree)
{
p_shape_tree.remove(this.tree_entries);
}
public int tree_shape_count(ShapeTree p_shape_tree)
{
return 1;
}
public TileShape get_tree_shape(ShapeTree p_shape_tree, int p_index)
{
return this.get_shape();
}
public int shape_layer(int p_index)
{
return this.get_layer();
}
public boolean is_obstacle(int p_net_no)
{
return true;
}
public boolean is_trace_obstacle(int p_net_no)
{
return true;
}
/**
* Will be called, when the room overlaps with net dependent objects.
*/
public void set_net_dependent()
{
this.room_is_net_dependent = true;
}
/**
* Returns, if the room overlaps with net dependent objects.
* In this case it cannot be retained, when the net number changes in autorouting.
*/
public boolean is_net_dependent()
{
return this.room_is_net_dependent;
}
/**
* Returns the list doors to target items of this room
*/
public Collection<TargetItemExpansionDoor> get_target_doors()
{
return this.target_doors;
}
/**
* Adds p_door to the list of target doors of this room.
*/
public void add_target_door(TargetItemExpansionDoor p_door)
{
this.target_doors.add(p_door);
}
public boolean remove_door(ExpandableObject p_door)
{
boolean result;
if (p_door instanceof TargetItemExpansionDoor)
{
result = this.target_doors.remove(p_door);
}
else
{
result = super.remove_door(p_door);
}
return result;
}
public SearchTreeObject get_object()
{
return this;
}
/**
* Calculates the doors to the start and destination items of the eu.mihosoft.freerouting.autoroute algorithm.
*/
public void calculate_target_doors(ShapeTree.TreeEntry p_own_net_object, int p_net_no, ShapeSearchTree p_autoroute_search_tree)
{
this.set_net_dependent();
if (p_own_net_object.object instanceof Connectable)
{
Connectable curr_object = (Connectable) p_own_net_object.object;
if (curr_object.contains_net(p_net_no))
{
TileShape curr_connection_shape =
curr_object.get_trace_connection_shape(p_autoroute_search_tree, p_own_net_object.shape_index_in_object);
if (curr_connection_shape != null && this.get_shape().intersects(curr_connection_shape))
{
Item curr_item = (Item) curr_object;
TargetItemExpansionDoor new_target_door =
new TargetItemExpansionDoor(curr_item, p_own_net_object.shape_index_in_object, this,
p_autoroute_search_tree);
this.add_target_door(new_target_door);
}
}
}
}
/**
* Draws the shape of this room.
*/
public void draw(java.awt.Graphics p_graphics, eu.mihosoft.freerouting.boardgraphics.GraphicsContext p_graphics_context, double p_intensity)
{
java.awt.Color draw_color = p_graphics_context.get_trace_colors(false)[this.get_layer()];
double layer_visibility = p_graphics_context.get_layer_visibility(this.get_layer());
p_graphics_context.fill_area(this.get_shape(), p_graphics, draw_color, p_intensity * layer_visibility);
p_graphics_context.draw_boundary(this.get_shape(), 0, draw_color, p_graphics, layer_visibility);
}
/**
* Check, if this FreeSpaceExpansionRoom is valid.
*/
public boolean validate( AutorouteEngine p_autoroute_engine)
{
boolean result = true;
Collection<ShapeTree.TreeEntry> overlapping_objects = new LinkedList<ShapeTree.TreeEntry>();
int [] net_no_arr = new int[1];
net_no_arr[0] = p_autoroute_engine.get_net_no();
p_autoroute_engine.autoroute_search_tree.overlapping_tree_entries( this.get_shape(), this.get_layer(),
net_no_arr, overlapping_objects);
Iterator<ShapeTree.TreeEntry> it = overlapping_objects.iterator();
while (it.hasNext())
{
ShapeTree.TreeEntry curr_entry = it.next();
if (curr_entry.object == this)
{
continue;
}
SearchTreeObject curr_object = (SearchTreeObject) curr_entry.object;
if (!curr_object.is_trace_obstacle(p_autoroute_engine.get_net_no()))
{
continue;
}
if (curr_object.shape_layer(curr_entry.shape_index_in_object) != get_layer())
{
continue;
}
TileShape curr_shape =
curr_object.get_tree_shape(p_autoroute_engine.autoroute_search_tree, curr_entry.shape_index_in_object);
TileShape intersection = this.get_shape().intersection(curr_shape);
if (intersection.dimension() > 1)
{
System.out.println("ExpansionRoom overlap conflict");
result = false;
}
}
return result;
}
/**
* Removes all doors and target doors from this room.
*/
public void clear_doors()
{
super.clear_doors();
this.target_doors = new LinkedList<TargetItemExpansionDoor>();
}
public void reset_doors()
{
super.reset_doors();
for (ExpandableObject curr_door : this.target_doors)
{
curr_door.reset();
}
}
/** The array of entries in the SearchTree. Consists of just one element */
private ShapeTree.Leaf [] tree_entries = null;
//** identification number for implementong the Comparable interfacw */
private final int id_no;
/** The list of doors to items of the own net */
private Collection<TargetItemExpansionDoor> target_doors;
private boolean room_is_net_dependent = false;
}