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

356 lines
10 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.
*
* BoardOutline.java
*
* Created on 18. August 2004, 07:24
*/
package eu.mihosoft.freerouting.board;
import eu.mihosoft.freerouting.geometry.planar.IntBox;
import eu.mihosoft.freerouting.geometry.planar.IntPoint;
import eu.mihosoft.freerouting.geometry.planar.TileShape;
import eu.mihosoft.freerouting.geometry.planar.PolylineShape;
import eu.mihosoft.freerouting.geometry.planar.PolylineArea;
import eu.mihosoft.freerouting.geometry.planar.Area;
import eu.mihosoft.freerouting.geometry.planar.Vector;
import eu.mihosoft.freerouting.geometry.planar.FloatPoint;
import eu.mihosoft.freerouting.boardgraphics.GraphicsContext;
/**
* Class describing a eu.mihosoft.freerouting.board outline.
*
* @author alfons
*/
public class BoardOutline extends Item implements java.io.Serializable
{
/** Creates a new instance of BoardOutline */
public BoardOutline(PolylineShape[] p_shapes, int p_clearance_class_no, int p_id_no, BasicBoard p_board)
{
super(new int[0], p_clearance_class_no, p_id_no, 0, FixedState.SYSTEM_FIXED, p_board);
shapes = p_shapes;
}
public int tile_shape_count()
{
int result;
if (this.keepout_outside_outline)
{
TileShape[] tile_shapes = this.get_keepout_area().split_to_convex();
if (tile_shapes == null)
{
// an error accured while dividing the area
result = 0;
}
else
{
result = tile_shapes.length * this.board.layer_structure.arr.length;
}
}
else
{
result = this.line_count() * this.board.layer_structure.arr.length;
}
return result;
}
public int shape_layer(int p_index)
{
int shape_count = this.tile_shape_count();
int result;
if (shape_count > 0)
{
result = p_index * this.board.layer_structure.arr.length / shape_count;
}
else
{
result = 0;
}
if (result < 0 || result >= this.board.layer_structure.arr.length)
{
System.out.println("BoardOutline.shape_layer: p_index out of range");
}
return result;
}
public boolean is_obstacle(Item p_other)
{
return !(p_other instanceof BoardOutline || p_other instanceof ObstacleArea);
}
public IntBox bounding_box()
{
IntBox result = IntBox.EMPTY;
for (PolylineShape curr_shape : this.shapes)
{
result = result.union(curr_shape.bounding_box());
}
return result;
}
public int first_layer()
{
return 0;
}
public int last_layer()
{
return this.board.layer_structure.arr.length - 1;
}
public boolean is_on_layer(int p_layer)
{
return true;
}
public void translate_by(Vector p_vector)
{
for (PolylineShape curr_shape : this.shapes)
{
curr_shape = curr_shape.translate_by(p_vector);
}
if (keepout_area != null)
{
keepout_area = keepout_area.translate_by(p_vector);
}
keepout_lines = null;
}
public void turn_90_degree(int p_factor, IntPoint p_pole)
{
for (PolylineShape curr_shape : this.shapes)
{
curr_shape = curr_shape.turn_90_degree(p_factor, p_pole);
}
if (keepout_area != null)
{
keepout_area = keepout_area.turn_90_degree(p_factor, p_pole);
}
keepout_lines = null;
}
public void rotate_approx(double p_angle_in_degree, FloatPoint p_pole)
{
double angle = Math.toRadians(p_angle_in_degree);
for (PolylineShape curr_shape : this.shapes)
{
curr_shape = curr_shape.rotate_approx(angle, p_pole);
}
if (keepout_area != null)
{
keepout_area = keepout_area.rotate_approx(angle, p_pole);
}
keepout_lines = null;
}
public void change_placement_side(IntPoint p_pole)
{
for (PolylineShape curr_shape : this.shapes)
{
curr_shape = curr_shape.mirror_vertical(p_pole);
}
if (keepout_area != null)
{
keepout_area = keepout_area.mirror_vertical(p_pole);
}
keepout_lines = null;
}
public double get_draw_intensity(GraphicsContext p_graphics_context)
{
return 1;
}
public int get_draw_priority()
{
return eu.mihosoft.freerouting.boardgraphics.Drawable.MAX_DRAW_PRIORITY;
}
public int shape_count()
{
return this.shapes.length;
}
public PolylineShape get_shape(int p_index)
{
if (p_index < 0 || p_index >= this.shapes.length)
{
System.out.println("BoardOutline.get_shape: p_index out of range");
return null;
}
return this.shapes[p_index];
}
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.BOARD_OUTLINE);
}
public java.awt.Color[] get_draw_colors(GraphicsContext p_graphics_context)
{
java.awt.Color[] color_arr = new java.awt.Color[this.board.layer_structure.arr.length];
java.awt.Color draw_color = p_graphics_context.get_outline_color();
for (int i = 0; i < color_arr.length; ++i)
{
color_arr[i] = draw_color;
}
return color_arr;
}
/**
* The eu.mihosoft.freerouting.board shape outside the outline curves, where a keepout will be generated
* The outline curves are holes of the keepout_area.
*/
Area get_keepout_area()
{
if (this.keepout_area == null)
{
PolylineShape[] hole_arr = new PolylineShape[this.shapes.length];
for (int i = 0; i < hole_arr.length; ++i)
{
hole_arr[i] = this.shapes[i];
}
keepout_area = new PolylineArea(this.board.bounding_box, hole_arr);
}
return this.keepout_area;
}
TileShape[] get_keepout_lines()
{
if (this.keepout_lines == null)
{
this.keepout_lines = new TileShape[0];
}
return this.keepout_lines;
}
public void draw(java.awt.Graphics p_g, GraphicsContext p_graphics_context, java.awt.Color[] p_color_arr, double p_intensity)
{
if (p_graphics_context == null || p_intensity <= 0)
{
return;
}
for (PolylineShape curr_shape : this.shapes)
{
FloatPoint[] draw_corners = curr_shape.corner_approx_arr();
FloatPoint[] closed_draw_corners = new FloatPoint[draw_corners.length + 1];
System.arraycopy(draw_corners, 0, closed_draw_corners, 0, draw_corners.length);
closed_draw_corners[closed_draw_corners.length - 1] = draw_corners[0];
p_graphics_context.draw(closed_draw_corners, HALF_WIDTH, p_color_arr[0], p_g, p_intensity);
}
}
public Item copy(int p_id_no)
{
return new BoardOutline(this.shapes, this.clearance_class_no(), p_id_no, this.board);
}
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("board_outline"));
print_clearance_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;
}
/**
* Returns, if keepout is generated outside the eu.mihosoft.freerouting.board outline.
* Otherwise only the line shapes of the outlines are inserted as keepout.
*/
public boolean keepout_outside_outline_generated()
{
return keepout_outside_outline;
}
/**
* Makes the area outside this Outline to Keepout, if p_valus = true.
* Reinserts this Outline into the search trees, if the value changes.
*/
public void generate_keepout_outside(boolean p_value)
{
if (p_value == keepout_outside_outline)
{
return;
}
keepout_outside_outline = p_value;
if (this.board == null || this.board.search_tree_manager == null)
{
return;
}
this.board.search_tree_manager.remove(this);
this.board.search_tree_manager.insert(this);
}
/**
* Returns the sum of the lines of all outline poligons.
*/
public int line_count()
{
int result = 0;
for (PolylineShape curr_shape : this.shapes)
{
result += curr_shape.border_line_count();
}
return result;
}
/**
* Returns the half width of the lines of this outline.
*/
public int get_half_width()
{
return HALF_WIDTH;
}
protected TileShape[] calculate_tree_shapes(ShapeSearchTree p_search_tree)
{
return p_search_tree.calculate_tree_shapes(this);
}
/** The eu.mihosoft.freerouting.board shapes inside the outline curves. */
private PolylineShape[] shapes;
/**
* The eu.mihosoft.freerouting.board shape outside the outline curves, where a keepout will be generated
* The outline curves are holes of the keepout_area.
*/
private Area keepout_area = null;
/**
* Used instead of keepout_area if only the line shapes of the outlines are inserted as keepout.
*/
private TileShape[] keepout_lines = null;
private boolean keepout_outside_outline = false;
private static final int HALF_WIDTH = 100;
}