コード例 #1
0
ファイル: Geometry.py プロジェクト: nerginer/Swoop
    def __init__(self, cgal_elem, swoop_elem):
        from CGAL.CGAL_Kernel import \
            Segment_2,\
            Polygon_2,\
            Point_2,\
            Bbox_2,\
            Iso_rectangle_2,\
            do_intersect
        self.cgal_elem = cgal_elem
        self.swoop_elem = swoop_elem
        bbox = cgal_elem.bbox()
        self.rect = Rectangle.from_cgal_bbox(bbox, check=False)

        #do_intersect only works with iso_rectangle, not bbox
        self.iso_rect = Iso_rectangle_2(bbox.xmin(), bbox.ymin(), bbox.xmax(), bbox.ymax())
コード例 #2
0
    def __init__(self, cgal_elem, swoop_elem):
        from CGAL.CGAL_Kernel import \
            Segment_2,\
            Polygon_2,\
            Point_2,\
            Bbox_2,\
            Iso_rectangle_2,\
            do_intersect
        self.cgal_elem = cgal_elem
        self.swoop_elem = swoop_elem
        bbox = cgal_elem.bbox()
        self.rect = Rectangle.from_cgal_bbox(bbox, check=False)

        #do_intersect only works with iso_rectangle, not bbox
        self.iso_rect = Iso_rectangle_2(bbox.xmin(), bbox.ymin(), bbox.xmax(),
                                        bbox.ymax())
コード例 #3
0
ファイル: Geometry.py プロジェクト: nerginer/Swoop
    def get_bounding_box(self, layer=None, type=None):
        """
        Get the minimum bounding box enclosing this list of primitive elements
        More accurate than self._get_cgal_elem().bbox(), because it accounts for segment width

        :param layer: Swoop layer to filter on
        """
        def max_min(vertex_list, width=None):
            max = np.maximum.reduce(vertex_list)
            min = np.minimum.reduce(vertex_list)
            if width is not None:
                radius = np.array([width, width]) / 2.0
                max += radius
                min -= radius
            return max,min

        if isinstance(self, Swoop.Polygon):
            vertices = [v.get_point() for v in self.get_vertices()]
            return Rectangle(*max_min(vertices, self.get_width()))
        elif isinstance(self, Swoop.Wire):
            if self.get_curve() is not None:
                theta = math.radians(self.get_curve()) # angle swept by arc
                theta = math.fmod(theta, 2*math.pi)
                p1 = self.get_point(0)  # 2 points on the circle
                p2 = self.get_point(1)
                return arc_bounding_box(p1, p2, theta).pad(self.get_width() / 2.0)
            else:
                vertices = [self.get_point(0), self.get_point(1)]
                return Rectangle(*max_min(vertices, self.get_width()), check=False)
        elif isinstance(self, Swoop.Rectangle):
            #get_cgal_elem already handles rotation
            bbox = self._get_cgal_elem().bbox()
            return Rectangle.from_cgal_bbox(bbox, check=False)
        elif isinstance(self, Swoop.Via) or isinstance(self, Swoop.Pad):
            #These assume default settings
            #Unfortunately, restring can change the sizes of things after import

            center = self.get_point()
            if self.get_diameter() is None:
                # Gotta figure it out from drill
                if self.get_drill() < 1.0:
                    diameter = self.get_drill() + 0.5
                else:
                    diameter = self.get_drill()*1.5
            else:
                diameter = self.get_diameter()
            radius = diameter/2.0 * np.ones(2)

            angle = 0.0
            if isinstance(self, Swoop.Pad) and self.get_rot() is not None:
                angle_m = angle_match(self.get_rot())
                angle = angle_m['angle']
                if angle_m['mirrored']:
                    angle = 180.0 - angle
            rotate_matrix = Rectangle.rotation_matrix(math.radians(angle))

            if self.get_shape() in ['long', 'offset']:
                # This is basically a square pad with 180º arc endcaps
                if self.get_shape()=='offset':
                    center[0] += diameter/2.0   # Center is offset to the left, correct it
                rect = Rectangle(center - radius, center + radius)
                verts = list(rect.vertices())
                verts = map(lambda v: rotate_matrix.dot(v - center) + center, verts)
                left_cap = arc_bounding_box(verts[0], verts[3], pi)
                right_cap = arc_bounding_box(verts[2], verts[1], pi)

                rect = Rectangle.union(rect, left_cap)
                rect = Rectangle.union(rect, right_cap)
                return rect
            elif self.get_shape()=='octagon':
                vertex = np.array([diameter/2.0,
                                   diameter/2.0 * math.tan(2*pi / 16 )])
                vertex = rotate_matrix.dot(vertex)
                vertices = []
                rot = Rectangle.rotation_matrix(2*pi/8)
                for i in xrange(8):
                    vertices.append(vertex.copy() + center)
                    vertex = rot.dot(vertex)
                return Rectangle.from_vertices(vertices, check=True)
            else:
                rect = Rectangle(center - radius, center + radius)
                if self.get_shape()=='square':
                    rect.rotate_resize(angle,origin=center)
                return rect
        elif isinstance(self, Swoop.Smd):
            center = self.get_point()
            radius = np.array([self.get_dx(), self.get_dy()]) / 2.0
            if self.get_rot() is not None:
                angle = angle_match(self.get_rot())
                radius = abs(Rectangle.rotation_matrix(math.radians(angle['angle'])).dot(radius))
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Circle):
            center = self.get_point()
            radius = np.ones(2) * (self.get_radius() + self.get_width()/2.0)
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Hole):
            center = self.get_point()
            radius = np.ones(2) * self.get_drill()/2.0
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Element):
            # Element objects do not have enough information for the bounding box
            # That gets set in the constructor
            if hasattr(self,"_extension_geo_elem"):
                return self._extension_geo_elem.rect
            else:
                tform = self.get_transform()
                bbox = self.find_package().get_bounding_box(layer=layer, type=type)
                if bbox is None:
                    return None
                return tform.apply(bbox)
        elif isinstance(self, Swoop.Package):
            rect = None
            for c in self.get_children():
                if ((layer is None) or (hasattr(c,"get_layer") and c.get_layer()==layer))\
                        and ((type is None) or isinstance(c, type)):
                    r = c.get_bounding_box()
                    if r is not None:
                        if rect is None:
                            rect = r
                        rect = Rectangle.union(rect, r)
            return rect
        else:
            return None
コード例 #4
0
    def get_bounding_box(self, layer=None, type=None):
        """
        Get the minimum bounding box enclosing this list of primitive elements
        More accurate than self._get_cgal_elem().bbox(), because it accounts for segment width

        :param layer: Swoop layer to filter on
        """
        def max_min(vertex_list, width=None):
            max = np.maximum.reduce(vertex_list)
            min = np.minimum.reduce(vertex_list)
            if width is not None:
                radius = np.array([width, width]) / 2.0
                max += radius
                min -= radius
            return max, min

        if isinstance(self, Swoop.Polygon):
            vertices = [v.get_point() for v in self.get_vertices()]
            return Rectangle(*max_min(vertices, self.get_width()))
        elif isinstance(self, Swoop.Wire):
            if self.get_curve() is not None:
                theta = math.radians(self.get_curve())  # angle swept by arc
                theta = math.fmod(theta, 2 * math.pi)
                p1 = self.get_point(0)  # 2 points on the circle
                p2 = self.get_point(1)
                return arc_bounding_box(p1, p2,
                                        theta).pad(self.get_width() / 2.0)
            else:
                vertices = [self.get_point(0), self.get_point(1)]
                return Rectangle(*max_min(vertices, self.get_width()),
                                 check=False)
        elif isinstance(self, Swoop.Rectangle):
            #get_cgal_elem already handles rotation
            bbox = self._get_cgal_elem().bbox()
            return Rectangle.from_cgal_bbox(bbox, check=False)
        elif isinstance(self, Swoop.Via) or isinstance(self, Swoop.Pad):
            #These assume default settings
            #Unfortunately, restring can change the sizes of things after import

            center = self.get_point()
            if self.get_diameter() is None:
                # Gotta figure it out from drill
                if self.get_drill() < 1.0:
                    diameter = self.get_drill() + 0.5
                else:
                    diameter = self.get_drill() * 1.5
            else:
                diameter = self.get_diameter()
            radius = diameter / 2.0 * np.ones(2)

            angle = 0.0
            if isinstance(self, Swoop.Pad) and self.get_rot() is not None:
                angle_m = angle_match(self.get_rot())
                angle = angle_m['angle']
                if angle_m['mirrored']:
                    angle = 180.0 - angle
            rotate_matrix = Rectangle.rotation_matrix(math.radians(angle))

            if self.get_shape() in ['long', 'offset']:
                # This is basically a square pad with 180º arc endcaps
                if self.get_shape() == 'offset':
                    center[
                        0] += diameter / 2.0  # Center is offset to the left, correct it
                rect = Rectangle(center - radius, center + radius)
                verts = list(rect.vertices())
                verts = [rotate_matrix.dot(v - center) + center for v in verts]
                left_cap = arc_bounding_box(verts[0], verts[3], pi)
                right_cap = arc_bounding_box(verts[2], verts[1], pi)

                rect = Rectangle.union(rect, left_cap)
                rect = Rectangle.union(rect, right_cap)
                return rect
            elif self.get_shape() == 'octagon':
                vertex = np.array(
                    [diameter / 2.0, diameter / 2.0 * math.tan(2 * pi / 16)])
                vertex = rotate_matrix.dot(vertex)
                vertices = []
                rot = Rectangle.rotation_matrix(2 * pi / 8)
                for i in range(8):
                    vertices.append(vertex.copy() + center)
                    vertex = rot.dot(vertex)
                return Rectangle.from_vertices(vertices, check=True)
            else:
                rect = Rectangle(center - radius, center + radius)
                if self.get_shape() == 'square':
                    rect.rotate_resize(angle, origin=center)
                return rect
        elif isinstance(self, Swoop.Smd):
            center = self.get_point()
            radius = np.array([self.get_dx(), self.get_dy()]) / 2.0
            if self.get_rot() is not None:
                angle = angle_match(self.get_rot())
                radius = abs(
                    Rectangle.rotation_matrix(math.radians(
                        angle['angle'])).dot(radius))
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Circle):
            center = self.get_point()
            radius = np.ones(2) * (self.get_radius() + self.get_width() / 2.0)
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Hole):
            center = self.get_point()
            radius = np.ones(2) * self.get_drill() / 2.0
            return Rectangle(center - radius, center + radius)
        elif isinstance(self, Swoop.Element):
            # Element objects do not have enough information for the bounding box
            # That gets set in the constructor
            if hasattr(self, "_extension_geo_elem"):
                return self._extension_geo_elem.rect
            else:
                tform = self.get_transform()
                bbox = self.find_package().get_bounding_box(layer=layer,
                                                            type=type)
                if bbox is None:
                    return None
                return tform.apply(bbox)
        elif isinstance(self, Swoop.Package):
            rect = None
            for c in self.get_children():
                if ((layer is None) or (hasattr(c,"get_layer") and c.get_layer()==layer))\
                        and ((type is None) or isinstance(c, type)):
                    r = c.get_bounding_box()
                    if r is not None:
                        if rect is None:
                            rect = r
                        rect = Rectangle.union(rect, r)
            return rect
        else:
            return None