snapshot 2019-04-20 13:34:52.427189
This commit is contained in:
		
							parent
							
								
									fa66e09f9b
								
							
						
					
					
						commit
						bab12add10
					
				| @ -15,7 +15,7 @@ import logging | ||||
| 
 | ||||
| from .utils import mangle_name, make_dose_table | ||||
| from .. import Pattern, SubPattern, GridRepetition, PatternError, Label, Shape | ||||
| from ..shapes import Polygon | ||||
| from ..shapes import Polygon, Path | ||||
| from ..utils import rotation_matrix_2d, get_bit, set_bit, vector2, is_scalar | ||||
| from ..utils import remove_colinear_vertices | ||||
| 
 | ||||
| @ -272,76 +272,23 @@ def read(filename: str, | ||||
|                 pat.shapes.append(shape) | ||||
| 
 | ||||
|             if isinstance(element, gdsii.elements.Path): | ||||
|                 if element.path_type == 0: | ||||
|                     #cap = Path.Cap.Flush | ||||
|                     extension = 0.0 | ||||
|                 elif element.path_type in (1, 4): | ||||
|                     raise PatternError('Round-ended and custom paths (types 1 and 4) are not implemented yet') | ||||
|                 elif element.path_type == 2: | ||||
|                     extension = element.width / 2 | ||||
|                 cap_map = {0: Path.Cap.Flush, | ||||
|                            1: Path.Cap.Circle, | ||||
|                            2: Path.Cap.Square, | ||||
|                           #3: custom? | ||||
|                           } | ||||
|                 if element.path_type in cap_map: | ||||
|                     cap = cap_map[element.path_type] | ||||
|                 else: | ||||
|                     raise PatternError('Unrecognized path type: {}'.format(element.path_type)) | ||||
| 
 | ||||
|                 if element.width == 0: | ||||
|                     continue | ||||
| 
 | ||||
|                 v = remove_colinear_vertices(numpy.array(element.xy, dtype=float), closed_path=False) | ||||
|                 dv = numpy.diff(v, axis=0) | ||||
|                 dvdir = dv / numpy.sqrt((dv * dv).sum(axis=1))[:, None] | ||||
|                 perp = dvdir[:, ::-1] * [[1, -1]] * element.width / 2 | ||||
| 
 | ||||
|                 # add extension | ||||
|                 v[0] -= dvdir[0] * extension | ||||
|                 v[-1] += dvdir[-1] * extension | ||||
| 
 | ||||
|                 # Find intersections of expanded sides | ||||
|                 As = numpy.stack((dv[:-1], -dv[1:]), axis=2) | ||||
|                 bs = v[1:-1] - v[:-2] + perp[1:] - perp[:-1] | ||||
|                 ds = v[1:-1] - v[:-2] - perp[1:] + perp[:-1] | ||||
| 
 | ||||
|                 rp = numpy.linalg.solve(As, bs)[:, 0, None] | ||||
|                 rn = numpy.linalg.solve(As, ds)[:, 0, None] | ||||
| 
 | ||||
|                 intersection_p = v[:-2] + rp * dv[:-1] + perp[:-1] | ||||
|                 intersection_n = v[:-2] + rn * dv[:-1] - perp[:-1] | ||||
| 
 | ||||
|                 towards_perp = (dv[1:] * perp[:-1]).sum(axis=1) > 0 # path bends towards previous perp? | ||||
| #               straight = (dv[1:] * perp[:-1]).sum(axis=1) == 0    # path is straight | ||||
|                 acute = (dv[1:] * dv[:-1]).sum(axis=1) < 0          # angle is acute? | ||||
| 
 | ||||
| 
 | ||||
|                 o0 = [v[0] + perp[0]] | ||||
|                 o1 = [v[0] - perp[0]] | ||||
|                 for i in range(dv.shape[0] - 1): | ||||
|                     if towards_perp[i]: | ||||
|                         o0.append(intersection_p[i]) | ||||
|                         if acute[i]: | ||||
|                             o1.append(intersection_n[i]) | ||||
|                         else: | ||||
|                             # Opposite is >270 | ||||
|                             pt0 = v[i + 1] - perp[i + 0] + dvdir[i + 0] * element.width / 2 | ||||
|                             pt1 = v[i + 1] - perp[i + 1] - dvdir[i + 1] * element.width / 2 | ||||
|                             o1 += [pt0, pt1] | ||||
|                     else: | ||||
|                         o1.append(intersection_n[i]) | ||||
|                         if acute[i]: | ||||
|                             # > 270 | ||||
|                             pt0 = v[i + 1] + perp[i + 0] + dvdir[i + 0] * element.width / 2 | ||||
|                             pt1 = v[i + 1] + perp[i + 1] - dvdir[i + 1] * element.width / 2 | ||||
|                             o0 += [pt0, pt1] | ||||
|                         else: | ||||
|                             o0.append(intersection_p[i]) | ||||
|                 o0.append(v[-1] + perp[-1]) | ||||
|                 o1.append(v[-1] - perp[-1]) | ||||
|                 verts = numpy.vstack((o0, o1[::-1])) | ||||
| 
 | ||||
|                 if use_dtype_as_dose: | ||||
|                     shape = Polygon(vertices=verts, | ||||
|                                     dose=element.data_type, | ||||
|                                     layer=element.layer) | ||||
|                     shape = Path(vertices=element.xy, | ||||
|                                  dose=element.data_type, | ||||
|                                  layer=element.layer) | ||||
|                 else: | ||||
|                     shape = Polygon(vertices=verts, | ||||
|                                     layer=(element.layer, element.data_type)) | ||||
|                     shape = Path(vertices=element.xy, | ||||
|                                  layer=(element.layer, element.data_type)) | ||||
|                 if clean_vertices: | ||||
|                     try: | ||||
|                         shape.clean_vertices() | ||||
|  | ||||
| @ -153,7 +153,7 @@ class Arc(Shape): | ||||
|         self.width = width | ||||
|         self.offset = offset | ||||
|         self.rotation = rotation | ||||
|         [self.mirror(a) for a in a, do in enumerate(mirrored) if do] | ||||
|         [self.mirror(a) for a, do in enumerate(mirrored) if do] | ||||
|         self.layer = layer | ||||
|         self.dose = dose | ||||
|         self.poly_num_points = poly_num_points | ||||
|  | ||||
| @ -92,7 +92,7 @@ class Ellipse(Shape): | ||||
|         self.radii = radii | ||||
|         self.offset = offset | ||||
|         self.rotation = rotation | ||||
|         [self.mirror(a) for a in a, do in enumerate(mirrored) if do] | ||||
|         [self.mirror(a) for a, do in enumerate(mirrored) if do] | ||||
|         self.layer = layer | ||||
|         self.dose = dose | ||||
|         self.poly_num_points = poly_num_points | ||||
|  | ||||
| @ -127,7 +127,7 @@ class Path(Shape): | ||||
|         self.width = width | ||||
|         self.cap = cap | ||||
|         self.rotate(rotation) | ||||
|         [self.mirror(a) for a in a, do in enumerate(mirrored) if do] | ||||
|         [self.mirror(a) for a, do in enumerate(mirrored) if do] | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def travel(travel_pairs: Tuple[Tuple[float, float]], | ||||
| @ -142,11 +142,12 @@ class Path(Shape): | ||||
|         """ | ||||
|         TODO | ||||
| 
 | ||||
|         :param rotation: Rotation counterclockwise, in radians | ||||
| 
 | ||||
|         :param offset: Offset, default (0, 0) | ||||
|         :param rotation: Rotation counterclockwise, in radians | ||||
|         :param layer: Layer, default 0 | ||||
|         :param dose: Dose, default 1.0 | ||||
|         :return: A Polygon object containing the requested square | ||||
|         :return: The resulting Path object | ||||
|         """ | ||||
|         direction = numpy.array([1, 0]) | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| from typing import List | ||||
| from typing import List, Tuple | ||||
| import copy | ||||
| import numpy | ||||
| from numpy import pi | ||||
| @ -82,7 +82,7 @@ class Polygon(Shape): | ||||
|         self.vertices = vertices | ||||
|         self.offset = offset | ||||
|         self.rotate(rotation) | ||||
|         [self.mirror(a) for a in a, do in enumerate(mirrored) if do] | ||||
|         [self.mirror(a) for a, do in enumerate(mirrored) if do] | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def square(side_length: float, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user