832 lines
29 KiB
Java
832 lines
29 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.
|
|
*
|
|
* Shape.java
|
|
*
|
|
* Created on 16. Mai 2004, 11:09
|
|
*/
|
|
package designformats.specctra;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
|
|
import geometry.planar.PolylineShape;
|
|
import datastructures.IndentFileWriter;
|
|
import datastructures.IdentifierType;
|
|
|
|
/**
|
|
* Describes a shape in a Specctra dsn file.
|
|
*
|
|
* @author alfons
|
|
*/
|
|
public abstract class Shape
|
|
{
|
|
|
|
/**
|
|
* Writes a shape scope to a Specctra dsn file.
|
|
*/
|
|
public abstract void write_scope(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException;
|
|
|
|
/**
|
|
* Writes a shape scope to a Specctra session file.
|
|
* In a session file all coordinates must be integer.
|
|
*/
|
|
public abstract void write_scope_int(IndentFileWriter p_file, IdentifierType p_identifier) throws java.io.IOException;
|
|
|
|
/**
|
|
* Reads shape scope from a Specctra dsn file.
|
|
* If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers.
|
|
*/
|
|
public static final Shape read_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
Shape result = null;
|
|
try
|
|
{
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
// overread the open bracket
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
|
|
if (next_token == Keyword.RECTANGLE)
|
|
{
|
|
|
|
result = Shape.read_rectangle_scope(p_scanner, p_layer_structure);
|
|
}
|
|
else if (next_token == Keyword.POLYGON)
|
|
{
|
|
|
|
result = Shape.read_polygon_scope(p_scanner, p_layer_structure);
|
|
}
|
|
else if (next_token == Keyword.CIRCLE)
|
|
{
|
|
|
|
result = Shape.read_circle_scope(p_scanner, p_layer_structure);
|
|
}
|
|
else if (next_token == Keyword.POLYGON_PATH)
|
|
{
|
|
result = Shape.read_polygon_path_scope(p_scanner, p_layer_structure);
|
|
}
|
|
else
|
|
{
|
|
// not a shape scope, skip it.
|
|
ScopeKeyword.skip_scope(p_scanner);
|
|
}
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reads an object of type PolylinePath from the dsn-file.
|
|
*/
|
|
public static PolylinePath read_polyline_path_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
try
|
|
{
|
|
Layer layer = null;
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.PCB_SCOPE)
|
|
{
|
|
layer = Layer.PCB;
|
|
}
|
|
else if (next_token == Keyword.SIGNAL)
|
|
{
|
|
layer = Layer.SIGNAL;
|
|
}
|
|
else
|
|
{
|
|
if (p_layer_structure == null)
|
|
{
|
|
System.out.println("PolylinePath.read_scope: only layer types pcb or signal expected");
|
|
return null;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("PolylinePath.read_scope: layer name string expected");
|
|
return null;
|
|
}
|
|
int layer_no = p_layer_structure.get_no((String) next_token);
|
|
if (layer_no < 0 || layer_no >= p_layer_structure.arr.length)
|
|
{
|
|
System.out.print("Shape.read_polyline_path_scope: layer name ");
|
|
System.out.print((String) next_token);
|
|
System.out.println(" not found in layer structure ");
|
|
return null;
|
|
}
|
|
layer = p_layer_structure.arr[layer_no];
|
|
}
|
|
Collection<Object> corner_list = new LinkedList<Object>();
|
|
|
|
// read the width and the corners of the path
|
|
for (;;)
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
corner_list.add(next_token);
|
|
}
|
|
if (corner_list.size() < 5)
|
|
{
|
|
System.out.println("PolylinePath.read_scope: to few numbers in scope");
|
|
return null;
|
|
}
|
|
Iterator<Object> it = corner_list.iterator();
|
|
double width = 0;
|
|
Object next_object = it.next();
|
|
if (next_object instanceof Double)
|
|
{
|
|
width = ((Double) next_object).doubleValue();
|
|
}
|
|
else if (next_object instanceof Integer)
|
|
{
|
|
width = ((Integer) next_object).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("PolylinePath.read_scope: number expected");
|
|
return null;
|
|
}
|
|
double[] corner_arr = new double[corner_list.size() - 1];
|
|
for (int i = 0; i < corner_arr.length; ++i)
|
|
{
|
|
next_object = it.next();
|
|
if (next_object instanceof Double)
|
|
{
|
|
corner_arr[i] = ((Double) next_object).doubleValue();
|
|
}
|
|
else if (next_object instanceof Integer)
|
|
{
|
|
corner_arr[i] = ((Integer) next_object).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: number expected");
|
|
return null;
|
|
}
|
|
|
|
}
|
|
return new PolylinePath(layer, width, corner_arr);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("PolylinePath.read_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads a shape , which may contain holes from a specctra dsn-file.
|
|
* The first shape in the shape_list of the result is the border of the area.
|
|
* The other shapes in the shape_list are holes (windows).
|
|
*/
|
|
public static final ReadAreaScopeResult read_area_scope(Scanner p_scanner,
|
|
LayerStructure p_layer_structure, boolean p_skip_window_scopes)
|
|
{
|
|
Collection<Shape> shape_list = new LinkedList<Shape>();
|
|
String clearance_class_name = null;
|
|
String area_name = null;
|
|
boolean result_ok = true;
|
|
Object next_token = null;
|
|
try
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_area_scope: IO error scanning file");
|
|
return null;
|
|
}
|
|
if (next_token instanceof String)
|
|
{
|
|
String curr_name = (String) next_token;
|
|
if (!curr_name.isEmpty())
|
|
{
|
|
area_name = curr_name;
|
|
}
|
|
}
|
|
Shape curr_shape = Shape.read_scope(p_scanner, p_layer_structure);
|
|
if (curr_shape == null)
|
|
{
|
|
result_ok = false;
|
|
}
|
|
shape_list.add(curr_shape);
|
|
next_token = null;
|
|
for (;;)
|
|
{
|
|
Object prev_token = next_token;
|
|
try
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_area_scope: IO error scanning file");
|
|
return null;
|
|
}
|
|
if (next_token == null)
|
|
{
|
|
System.out.println("Shape.read_area_scope: unexpected end of file");
|
|
return null;
|
|
}
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
// end of scope
|
|
break;
|
|
}
|
|
|
|
if (prev_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
// a new scope is expected
|
|
if (next_token == Keyword.WINDOW && !p_skip_window_scopes)
|
|
{
|
|
Shape hole_shape = Shape.read_scope(p_scanner, p_layer_structure);
|
|
shape_list.add(hole_shape);
|
|
// overread closing bracket
|
|
try
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_area_scope: IO error scanning file");
|
|
return null;
|
|
}
|
|
if (next_token != Keyword.CLOSED_BRACKET)
|
|
{
|
|
System.out.println("Shape.read_area_scope: closed bracket expected");
|
|
return null;
|
|
}
|
|
|
|
}
|
|
else if (next_token == Keyword.CLEARANCE_CLASS)
|
|
{
|
|
clearance_class_name = DsnFile.read_string_scope(p_scanner);
|
|
}
|
|
else
|
|
{
|
|
// skip unknown scope
|
|
ScopeKeyword.skip_scope(p_scanner);
|
|
}
|
|
}
|
|
}
|
|
if (!result_ok)
|
|
{
|
|
return null;
|
|
}
|
|
return new ReadAreaScopeResult(area_name, shape_list, clearance_class_name);
|
|
}
|
|
|
|
/**
|
|
* Reads a rectangle scope from a Specctra dsn file.
|
|
* If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers.
|
|
*/
|
|
public static Rectangle read_rectangle_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
try
|
|
{
|
|
Layer rect_layer = null;
|
|
double rect_coor[] = new double[4];
|
|
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.PCB_SCOPE)
|
|
{
|
|
rect_layer = Layer.PCB;
|
|
}
|
|
else if (next_token == Keyword.SIGNAL)
|
|
{
|
|
rect_layer = Layer.SIGNAL;
|
|
}
|
|
else if (p_layer_structure != null)
|
|
{
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope: layer name string expected");
|
|
return null;
|
|
}
|
|
String layer_name = (String) next_token;
|
|
int layer_no = p_layer_structure.get_no(layer_name);
|
|
if (layer_no < 0 || layer_no >= p_layer_structure.arr.length)
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope: layer name " + layer_name +
|
|
" not found in layer structure ");
|
|
}
|
|
else
|
|
{
|
|
rect_layer = p_layer_structure.arr[layer_no];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rect_layer = Layer.SIGNAL;
|
|
}
|
|
// fill the the rectangle
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
if (next_token instanceof Double)
|
|
{
|
|
rect_coor[i] = ((Double) next_token).doubleValue();
|
|
}
|
|
else if (next_token instanceof Integer)
|
|
{
|
|
rect_coor[i] = ((Integer) next_token).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope: number expected");
|
|
return null;
|
|
}
|
|
}
|
|
// overread the closing bracket
|
|
|
|
next_token = p_scanner.next_token();
|
|
if (next_token != Keyword.CLOSED_BRACKET)
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope ) expected");
|
|
return null;
|
|
}
|
|
if (rect_layer == null)
|
|
{
|
|
return null;
|
|
}
|
|
return new Rectangle(rect_layer, rect_coor);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads a closed polygon scope from a Specctra dsn file.
|
|
* If p_layer_structure == null, only Layer.PCB and Layer.Signal are expected, no induvidual layers.
|
|
*/
|
|
public static Polygon read_polygon_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
try
|
|
{
|
|
Layer polygon_layer = null;
|
|
boolean layer_ok = true;
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.PCB_SCOPE)
|
|
{
|
|
polygon_layer = Layer.PCB;
|
|
}
|
|
else if (next_token == Keyword.SIGNAL)
|
|
{
|
|
polygon_layer = Layer.SIGNAL;
|
|
}
|
|
else
|
|
{
|
|
if (p_layer_structure == null)
|
|
{
|
|
System.out.println("Shape.read_polygon_scope: only layer types pcb or signal expected");
|
|
return null;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("Shape.read_polygon_scope: layer name string expected");
|
|
return null;
|
|
}
|
|
int layer_no = p_layer_structure.get_no((String) next_token);
|
|
if (layer_no < 0 || layer_no >= p_layer_structure.arr.length)
|
|
{
|
|
System.out.print("Shape.read_polygon_scope: layer name ");
|
|
System.out.print((String) next_token);
|
|
System.out.println(" not found in layer structure ");
|
|
layer_ok = false;
|
|
}
|
|
else
|
|
{
|
|
polygon_layer = p_layer_structure.arr[layer_no];
|
|
}
|
|
}
|
|
|
|
// overread the aperture width
|
|
next_token = p_scanner.next_token();
|
|
|
|
Collection<Object> coor_list = new LinkedList<Object>();
|
|
|
|
// read the coordinates of the polygon
|
|
for (;;)
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
if (next_token == null)
|
|
{
|
|
System.out.println("Shape.read_polygon_scope: unexpected end of file");
|
|
return null;
|
|
}
|
|
if (next_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
// unknown scope
|
|
ScopeKeyword.skip_scope(p_scanner);
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
coor_list.add(next_token);
|
|
}
|
|
if (!layer_ok)
|
|
{
|
|
return null;
|
|
}
|
|
double[] coor_arr = new double[coor_list.size()];
|
|
Iterator<Object> it = coor_list.iterator();
|
|
for (int i = 0; i < coor_arr.length; ++i)
|
|
{
|
|
Object next_object = it.next();
|
|
if (next_object instanceof Double)
|
|
{
|
|
coor_arr[i] = ((Double) next_object).doubleValue();
|
|
}
|
|
else if (next_object instanceof Integer)
|
|
{
|
|
coor_arr[i] = ((Integer) next_object).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_polygon_scope: number expected");
|
|
return null;
|
|
}
|
|
|
|
}
|
|
return new Polygon(polygon_layer, coor_arr);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Rectangle.read_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads a circle scope from a Specctra dsn file.
|
|
*/
|
|
public static Circle read_circle_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
try
|
|
{
|
|
Layer circle_layer = null;
|
|
boolean layer_ok = true;
|
|
double circle_coor[] = new double[3];
|
|
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.PCB_SCOPE)
|
|
{
|
|
circle_layer = Layer.PCB;
|
|
}
|
|
else if (next_token == Keyword.SIGNAL)
|
|
{
|
|
circle_layer = Layer.SIGNAL;
|
|
}
|
|
else
|
|
{
|
|
if (p_layer_structure == null)
|
|
{
|
|
System.out.println("Shape.read_circle_scope: p_layer_structure != null expected");
|
|
return null;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("Shape.read_circle_scope: string for layer_name expected");
|
|
return null;
|
|
}
|
|
int layer_no = p_layer_structure.get_no((String) next_token);
|
|
if (layer_no < 0 || layer_no >= p_layer_structure.arr.length)
|
|
{
|
|
System.out.print("Shape.read_circle_scope: layer with name ");
|
|
System.out.print((String) next_token);
|
|
System.out.println(" not found in layer stracture ");
|
|
layer_ok = false;
|
|
}
|
|
else
|
|
{
|
|
circle_layer = p_layer_structure.arr[layer_no];
|
|
}
|
|
}
|
|
// fill the the the coordinates
|
|
int curr_index = 0;
|
|
for (;;)
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
if (curr_index > 2)
|
|
{
|
|
System.out.println("Shape.read_circle_scope: closed bracket expected");
|
|
return null;
|
|
}
|
|
if (next_token instanceof Double)
|
|
{
|
|
circle_coor[curr_index] = ((Double) next_token).doubleValue();
|
|
}
|
|
else if (next_token instanceof Integer)
|
|
{
|
|
circle_coor[curr_index] = ((Integer) next_token).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_circle_scope: number expected");
|
|
return null;
|
|
}
|
|
++curr_index;
|
|
}
|
|
if (!layer_ok)
|
|
{
|
|
return null;
|
|
}
|
|
return new Circle(circle_layer, circle_coor);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_rectangle_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads an object of type Path from the dsn-file.
|
|
*/
|
|
public static PolygonPath read_polygon_path_scope(Scanner p_scanner, LayerStructure p_layer_structure)
|
|
{
|
|
try
|
|
{
|
|
Layer layer = null;
|
|
boolean layer_ok = true;
|
|
Object next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.PCB_SCOPE)
|
|
{
|
|
layer = Layer.PCB;
|
|
}
|
|
else if (next_token == Keyword.SIGNAL)
|
|
{
|
|
layer = Layer.SIGNAL;
|
|
}
|
|
else
|
|
{
|
|
if (p_layer_structure == null)
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: only layer types pcb or signal expected");
|
|
return null;
|
|
}
|
|
if (!(next_token instanceof String))
|
|
{
|
|
System.out.println("Path.read_scope: layer name string expected");
|
|
return null;
|
|
}
|
|
int layer_no = p_layer_structure.get_no((String) next_token);
|
|
if (layer_no < 0 || layer_no >= p_layer_structure.arr.length)
|
|
{
|
|
System.out.print("Shape.read_polygon_path_scope: layer with name ");
|
|
System.out.print((String) next_token);
|
|
System.out.println(" not found in layer structure ");
|
|
layer_ok = false;
|
|
}
|
|
else
|
|
{
|
|
layer = p_layer_structure.arr[layer_no];
|
|
}
|
|
}
|
|
Collection<Object> corner_list = new LinkedList<Object>();
|
|
|
|
// read the width and the corners of the path
|
|
for (;;)
|
|
{
|
|
next_token = p_scanner.next_token();
|
|
if (next_token == Keyword.OPEN_BRACKET)
|
|
{
|
|
// unknown scope
|
|
ScopeKeyword.skip_scope(p_scanner);
|
|
next_token = p_scanner.next_token();
|
|
}
|
|
if (next_token == Keyword.CLOSED_BRACKET)
|
|
{
|
|
break;
|
|
}
|
|
corner_list.add(next_token);
|
|
}
|
|
if (corner_list.size() < 5)
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: to few numbers in scope");
|
|
return null;
|
|
}
|
|
if (!layer_ok)
|
|
{
|
|
return null;
|
|
}
|
|
Iterator<Object> it = corner_list.iterator();
|
|
double width = 0;
|
|
Object next_object = it.next();
|
|
if (next_object instanceof Double)
|
|
{
|
|
width = ((Double) next_object).doubleValue();
|
|
}
|
|
else if (next_object instanceof Integer)
|
|
{
|
|
width = ((Integer) next_object).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: number expected");
|
|
return null;
|
|
}
|
|
double[] coordinate_arr = new double[corner_list.size() - 1];
|
|
for (int i = 0; i < coordinate_arr.length; ++i)
|
|
{
|
|
next_object = it.next();
|
|
if (next_object instanceof Double)
|
|
{
|
|
coordinate_arr[i] = ((Double) next_object).doubleValue();
|
|
}
|
|
else if (next_object instanceof Integer)
|
|
{
|
|
coordinate_arr[i] = ((Integer) next_object).intValue();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: number expected");
|
|
return null;
|
|
}
|
|
|
|
}
|
|
return new PolygonPath(layer, width, coordinate_arr);
|
|
}
|
|
catch (java.io.IOException e)
|
|
{
|
|
System.out.println("Shape.read_polygon_path_scope: IO error scanning file");
|
|
System.out.println(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Transforms a shape with holes to the board coordinate system.
|
|
* The first shape in the Collection p_area is the border,
|
|
* the other shapes are holes of the area.
|
|
*/
|
|
public static geometry.planar.Area transform_area_to_board(Collection<Shape> p_area, CoordinateTransform p_coordinate_transform)
|
|
{
|
|
int hole_count = p_area.size() - 1;
|
|
if (hole_count <= -1)
|
|
{
|
|
System.out.println("Shape.transform_area_to_board: p_area.size() > 0 expected");
|
|
return null;
|
|
}
|
|
Iterator<Shape> it = p_area.iterator();
|
|
Shape boundary = it.next();
|
|
geometry.planar.Shape boundary_shape = boundary.transform_to_board(p_coordinate_transform);
|
|
geometry.planar.Area result;
|
|
if (hole_count == 0)
|
|
{
|
|
result = boundary_shape;
|
|
}
|
|
else
|
|
{
|
|
// Area with holes
|
|
if (!(boundary_shape instanceof geometry.planar.PolylineShape))
|
|
{
|
|
System.out.println("Shape.transform_area_to_board: PolylineShape expected");
|
|
return null;
|
|
}
|
|
PolylineShape border = (PolylineShape) boundary_shape;
|
|
PolylineShape[] holes = new PolylineShape[hole_count];
|
|
for (int i = 0; i < holes.length; ++i)
|
|
{
|
|
geometry.planar.Shape hole_shape = it.next().transform_to_board(p_coordinate_transform);
|
|
if (!(hole_shape instanceof PolylineShape))
|
|
{
|
|
System.out.println("Shape.transform_area_to_board: PolylineShape expected");
|
|
return null;
|
|
}
|
|
holes[i] = (PolylineShape) hole_shape;
|
|
}
|
|
result = new geometry.planar.PolylineArea(border, holes);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Transforms the relative coordinates of a shape with holes to the board coordinate system.
|
|
* The first shape in the Collection p_area is the border,
|
|
* the other shapes are holes of the area.
|
|
*/
|
|
public static geometry.planar.Area transform_area_to_board_rel(Collection<Shape> p_area, CoordinateTransform p_coordinate_transform)
|
|
{
|
|
int hole_count = p_area.size() - 1;
|
|
if (hole_count <= -1)
|
|
{
|
|
System.out.println("Shape.transform_area_to_board_rel: p_area.size() > 0 expected");
|
|
return null;
|
|
}
|
|
Iterator<Shape> it = p_area.iterator();
|
|
Shape boundary = it.next();
|
|
geometry.planar.Shape boundary_shape = boundary.transform_to_board_rel(p_coordinate_transform);
|
|
geometry.planar.Area result;
|
|
if (hole_count == 0)
|
|
{
|
|
result = boundary_shape;
|
|
}
|
|
else
|
|
{
|
|
// Area with holes
|
|
if (!(boundary_shape instanceof geometry.planar.PolylineShape))
|
|
{
|
|
System.out.println("Shape.transform_area_to_board_rel: PolylineShape expected");
|
|
return null;
|
|
}
|
|
PolylineShape border = (PolylineShape) boundary_shape;
|
|
PolylineShape[] holes = new PolylineShape[hole_count];
|
|
for (int i = 0; i < holes.length; ++i)
|
|
{
|
|
geometry.planar.Shape hole_shape = it.next().transform_to_board_rel(p_coordinate_transform);
|
|
if (!(hole_shape instanceof PolylineShape))
|
|
{
|
|
System.out.println("Shape.transform_area_to_board: PolylineShape expected");
|
|
return null;
|
|
}
|
|
holes[i] = (PolylineShape) hole_shape;
|
|
}
|
|
result = new geometry.planar.PolylineArea(border, holes);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void write_hole_scope(IndentFileWriter p_file, IdentifierType p_identifier_type) throws java.io.IOException
|
|
{
|
|
p_file.start_scope();
|
|
p_file.write("window");
|
|
this.write_scope(p_file, p_identifier_type);
|
|
p_file.end_scope();
|
|
}
|
|
|
|
/**
|
|
* Transforms a specctra dsn shape to a geometry.planar.Shape.
|
|
*/
|
|
public abstract geometry.planar.Shape transform_to_board(CoordinateTransform p_coordinate_transform);
|
|
|
|
/**
|
|
* Returns the smallest axis parallel rectangle containing this shape.
|
|
*/
|
|
public abstract Rectangle bounding_box();
|
|
|
|
/**
|
|
* Transforms the relative (vector) coordinates of a specctra dsn shape to a geometry.planar.Shape.
|
|
*/
|
|
public abstract geometry.planar.Shape transform_to_board_rel(CoordinateTransform p_coordinate_transform);
|
|
|
|
protected Shape(Layer p_layer)
|
|
{
|
|
layer = p_layer;
|
|
}
|
|
public final Layer layer;
|
|
|
|
/**
|
|
* Contains the result of the function read_area_scope.
|
|
* area_name or clearance_class_name may be null, which means they are not provided.
|
|
*/
|
|
static class ReadAreaScopeResult
|
|
{
|
|
|
|
private ReadAreaScopeResult(String p_area_name, Collection<Shape> p_shape_list, String p_clearance_class_name)
|
|
{
|
|
area_name = p_area_name;
|
|
shape_list = p_shape_list;
|
|
clearance_class_name = p_clearance_class_name;
|
|
}
|
|
String area_name; // may be generated later on, if area_name is null.
|
|
final Collection<Shape> shape_list;
|
|
final String clearance_class_name;
|
|
}
|
|
}
|