267 lines
8.1 KiB
Java
267 lines
8.1 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.
|
|
*
|
|
* ComponentOutline.java
|
|
*
|
|
* Created on 28. November 2005, 06:42
|
|
*
|
|
*/
|
|
package eu.mihosoft.freerouting.board;
|
|
|
|
import java.awt.Color;
|
|
|
|
import eu.mihosoft.freerouting.geometry.planar.Area;
|
|
import eu.mihosoft.freerouting.geometry.planar.Vector;
|
|
import eu.mihosoft.freerouting.geometry.planar.Point;
|
|
import eu.mihosoft.freerouting.geometry.planar.IntPoint;
|
|
import eu.mihosoft.freerouting.geometry.planar.FloatPoint;
|
|
|
|
import eu.mihosoft.freerouting.boardgraphics.GraphicsContext;
|
|
|
|
/**
|
|
*
|
|
* @author Alfons Wirtz
|
|
*/
|
|
public class ComponentOutline extends Item implements java.io.Serializable
|
|
{
|
|
|
|
/** Creates a new instance of ComponentOutline */
|
|
public ComponentOutline(Area p_area, boolean p_is_front, Vector p_translation, double p_rotation_in_degree,
|
|
int p_component_no, FixedState p_fixed_state, BasicBoard p_board)
|
|
{
|
|
super(new int[0], 0, 0, p_component_no, p_fixed_state, p_board);
|
|
this.relative_area = p_area;
|
|
this.is_front = p_is_front;
|
|
this.translation = p_translation;
|
|
this.rotation_in_degree = p_rotation_in_degree;
|
|
}
|
|
|
|
public Item copy(int p_id_no)
|
|
{
|
|
return new ComponentOutline(this.relative_area, this.is_front, this.translation, this.rotation_in_degree,
|
|
this.get_component_no(), this.get_fixed_state(), this.board);
|
|
}
|
|
|
|
public boolean is_selected_by_filter(ItemSelectionFilter p_filter)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public int get_layer()
|
|
{
|
|
int result;
|
|
if (this.is_front)
|
|
{
|
|
result = 0;
|
|
}
|
|
else
|
|
{
|
|
result = this.board.get_layer_count() - 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int first_layer()
|
|
{
|
|
return get_layer();
|
|
}
|
|
|
|
public int last_layer()
|
|
{
|
|
return get_layer();
|
|
}
|
|
|
|
public boolean is_on_layer(int p_layer)
|
|
{
|
|
return get_layer() == p_layer;
|
|
}
|
|
|
|
public boolean is_obstacle(Item p_item)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public int shape_layer(int p_index)
|
|
{
|
|
return get_layer();
|
|
}
|
|
|
|
public int tile_shape_count()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
protected eu.mihosoft.freerouting.geometry.planar.TileShape[] calculate_tree_shapes(ShapeSearchTree p_search_tree)
|
|
{
|
|
return new eu.mihosoft.freerouting.geometry.planar.TileShape[0];
|
|
}
|
|
|
|
public double get_draw_intensity(GraphicsContext p_graphics_context)
|
|
{
|
|
return p_graphics_context.get_component_outline_color_intensity();
|
|
}
|
|
|
|
public Color[] get_draw_colors(GraphicsContext p_graphics_context)
|
|
{
|
|
Color[] color_arr = new java.awt.Color[this.board.layer_structure.arr.length];
|
|
Color front_draw_color = p_graphics_context.get_component_color(true);
|
|
for (int i = 0; i < color_arr.length - 1; ++i)
|
|
{
|
|
color_arr[i] = front_draw_color;
|
|
}
|
|
if (color_arr.length > 1)
|
|
{
|
|
color_arr[color_arr.length - 1] = p_graphics_context.get_component_color(false);
|
|
}
|
|
return color_arr;
|
|
}
|
|
|
|
public int get_draw_priority()
|
|
{
|
|
return eu.mihosoft.freerouting.boardgraphics.Drawable.MIDDLE_DRAW_PRIORITY;
|
|
}
|
|
|
|
public void draw(java.awt.Graphics p_g, GraphicsContext p_graphics_context, Color[] p_color_arr, double p_intensity)
|
|
{
|
|
if (p_graphics_context == null || p_intensity <= 0)
|
|
{
|
|
return;
|
|
}
|
|
Color color = p_color_arr[this.get_layer()];
|
|
double intensity = p_graphics_context.get_layer_visibility(this.get_layer()) * p_intensity;
|
|
|
|
double draw_width = Math.min (this.board.communication.get_resolution(Unit.MIL), 100); // problem with low resolution on Kicad
|
|
p_graphics_context.draw_boundary(this.get_area(), draw_width, color, p_g, intensity);
|
|
}
|
|
|
|
public eu.mihosoft.freerouting.geometry.planar.IntBox bounding_box()
|
|
{
|
|
return get_area().bounding_box();
|
|
}
|
|
|
|
public void translate_by(Vector p_vector)
|
|
{
|
|
this.translation = this.translation.add(p_vector);
|
|
clear_derived_data();
|
|
}
|
|
|
|
public void change_placement_side(IntPoint p_pole)
|
|
{
|
|
this.is_front = !this.is_front;
|
|
Point rel_location = Point.ZERO.translate_by(this.translation);
|
|
this.translation = rel_location.mirror_vertical(p_pole).difference_by(Point.ZERO);
|
|
clear_derived_data();
|
|
}
|
|
|
|
public void rotate_approx(double p_angle_in_degree, FloatPoint p_pole)
|
|
{
|
|
double turn_angle = p_angle_in_degree;
|
|
if (!this.is_front && this.board.components.get_flip_style_rotate_first())
|
|
{
|
|
turn_angle = 360 - p_angle_in_degree;
|
|
}
|
|
this.rotation_in_degree += turn_angle;
|
|
while (this.rotation_in_degree >= 360)
|
|
{
|
|
this.rotation_in_degree -= 360;
|
|
}
|
|
while (this.rotation_in_degree < 0)
|
|
{
|
|
this.rotation_in_degree += 360;
|
|
}
|
|
FloatPoint new_translation = this.translation.to_float().rotate(Math.toRadians(p_angle_in_degree), p_pole);
|
|
this.translation = new_translation.round().difference_by(Point.ZERO);
|
|
clear_derived_data();
|
|
}
|
|
|
|
public void turn_90_degree(int p_factor, IntPoint p_pole)
|
|
{
|
|
this.rotation_in_degree += p_factor * 90;
|
|
while (this.rotation_in_degree >= 360)
|
|
{
|
|
this.rotation_in_degree -= 360;
|
|
}
|
|
while (this.rotation_in_degree < 0)
|
|
{
|
|
this.rotation_in_degree += 360;
|
|
}
|
|
Point rel_location = Point.ZERO.translate_by(this.translation);
|
|
this.translation = rel_location.turn_90_degree(p_factor, p_pole).difference_by(Point.ZERO);
|
|
clear_derived_data();
|
|
}
|
|
|
|
public Area get_area()
|
|
{
|
|
if (this.precalculated_absolute_area == null)
|
|
{
|
|
if (this.relative_area == null)
|
|
{
|
|
System.out.println("ObstacleArea.get_area: area is null");
|
|
return null;
|
|
}
|
|
Area turned_area = this.relative_area;
|
|
if (!this.is_front && !this.board.components.get_flip_style_rotate_first())
|
|
{
|
|
turned_area = turned_area.mirror_vertical(Point.ZERO);
|
|
}
|
|
if (this.rotation_in_degree != 0)
|
|
{
|
|
double rotation = this.rotation_in_degree;
|
|
if (rotation % 90 == 0)
|
|
{
|
|
turned_area = turned_area.turn_90_degree(((int) rotation) / 90, Point.ZERO);
|
|
}
|
|
else
|
|
{
|
|
turned_area = turned_area.rotate_approx(Math.toRadians(rotation), FloatPoint.ZERO);
|
|
}
|
|
|
|
}
|
|
if (!this.is_front && this.board.components.get_flip_style_rotate_first())
|
|
{
|
|
turned_area = turned_area.mirror_vertical(Point.ZERO);
|
|
}
|
|
this.precalculated_absolute_area = turned_area.translate_by(this.translation);
|
|
}
|
|
return this.precalculated_absolute_area;
|
|
}
|
|
|
|
public void clear_derived_data()
|
|
{
|
|
precalculated_absolute_area = null;
|
|
}
|
|
|
|
public void print_info(ObjectInfoPanel p_window, java.util.Locale p_locale)
|
|
{
|
|
}
|
|
|
|
public boolean write(java.io.ObjectOutputStream p_stream)
|
|
{
|
|
try
|
|
{
|
|
p_stream.writeObject(this);
|
|
} catch (java.io.IOException e)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
private Area relative_area;
|
|
private transient Area precalculated_absolute_area = null;
|
|
private Vector translation;
|
|
private double rotation_in_degree;
|
|
private boolean is_front;
|
|
}
|