Exemplo n.º 1
0
def SVG2Graphic(filename, board, layer):
    # the internal coorinate space of pcbnew is 10E-6 mm. (a millionth of a mm)
    # the coordinate 121550000 corresponds to 121.550000
    SCALE = 1000000.0

    # here I load from drawing.svg in the current directory. You'll want to change that path.
    paths = parse_svg_path.parse_svg_path(filename)
    if not paths:
        raise ValueError('wasnt able to read any paths from file')

    for path in paths:
        for shape in path.group_by_bound_and_holes():

            lastPt = shape.bound[0]
            for pt in shape.bound[1:]:
                # I'm getting repeated points from the svg. haven't investigated why.
                if (pt == lastPt):
                    continue
                make_line(board, lastPt, pt, layer)
                lastPt = pt

            for hole in shape.holes:
                lastPt = hole[0]
                for pt in hole[1:]:
                    if (pt == lastPt):
                        continue
                    make_line(board, lastPt, pt, layer)
                    lastPt = pt
Exemplo n.º 2
0
def SVG2Zone(filename, board, layer, net):

    # the internal coorinate space of pcbnew is 10E-6 mm. (a millionth of a mm)
    # the coordinate 121550000 corresponds to 121.550000
    SCALE = 1000000.0


    # here I load from drawing.svg in the current directory. You'll want to change that path.
    paths = parse_svg_path.parse_svg_path(filename)
    if not paths:
        raise ValueError('wasnt able to read any paths from file')


    # things are a little tricky below, because the first boundary has its first
    # point passed into the creation of the new area. subsequent bounds are not
    # done that way.
    zone_container = None
    shape_poly_set = None

    for path in paths:
        for shape in path.group_by_bound_and_holes():
            shapeid = None
            if not shape_poly_set:
                # the call to GetNet() gets the netcode, an integer.
                zone_container = board.InsertArea(net.GetNet(), 0, layer,
                                                  int(shape.bound[0][0]*SCALE),
                                                  int(shape.bound[0][1]*SCALE),
                                                  pcbnew.CPolyLine.DIAGONAL_EDGE)
                shape_poly_set = zone_container.Outline()
                shapeid = 0
            else:
                shapeid = shape_poly_set.NewOutline()
                shape_poly_set.Append(int(shape.bound[0][0]*SCALE),
                                      int(shape.bound[0][1]*SCALE),
                                      shapeid)

            for pt in shape.bound[1:]:
                shape_poly_set.Append(int(pt[0]*SCALE), int(pt[1]*SCALE))

            for hole in shape.holes:
                hi = shape_poly_set.NewHole()
                # -1 to the third arg maintains the default behavior of
                # using the last outline.
                for pt in hole:
                    shape_poly_set.Append(int(pt[0]*SCALE), int(pt[1]*SCALE), -1, hi)

            zone_container.Hatch()
Exemplo n.º 3
0
    def main():
        args = parse_args()

        if args.test_mode:
            input_svg = "m385,854c31,-1 67,-16 95,4c17,11 44,19 58,4c7,-26 -5,-49 -8,-75c-9,-30 -15,-62 -12,-94c-8,-29 -1,-61 2,-91c4,-28 21,-53 31,-80c5,-23 18,-43 33,-61c12,-24 23,-49 27,-76c3,-20 9,-44 1,-64c-13,-22 -39,-33 -54,-53c-16,-13 -38,-24 -30,-50c-15,-8 -42,-2 -25,17c3,33 39,43 58,65c23,20 27,53 26,82c-9,28 -21,56 -30,86c-17,30 -30,63 -48,94c-10,25 -18,52 -25,80c-5,28 3,56 8,84c7,29 9,60 17,89c4,17 0,46 -21,23c-16,-16 -45,-9 -65,-5c-12,12 -52,-4 -39,23"
        else:
            input_svg = args.svg_path

        curvePoints = parse_svg_path(input_svg)
        points = bezier_to_lineseg(curvePoints,
                                   tolerance=args.tolerance,
                                   simplify_eps=args.distance)
        nodes, texcoords, indices = lathe_path(points,
                                               start_angle=args.startAngle,
                                               end_angle=args.endAngle,
                                               num_divisions=args.divisions,
                                               cap_start=args.capStart,
                                               cap_end=args.capEnd)

        if args.output_type == 'smesh':
            save_mesh(sys.stdout, nodes, indices, node_attrs=texcoords)
        elif args.output_type == 'wgljson':
            _min, _max = getExtents(nodes)
            obj = dict(
                arrays=dict(
                    position=np.reshape(nodes, [-1]).tolist(),
                    texcoord=np.reshape(texcoords, [-1]).tolist(),
                    indices=np.reshape(indices, [-1]).tolist(),
                ),
                extents=dict(
                    min=_min,
                    max=_max,
                ),
            )
            json.dump(obj,
                      sys.stdout,
                      ensure_ascii=False,
                      indent=2,
                      allow_nan=False)
        else:
            print(len(nodes), nodes)
            print(len(texcoords), texcoords)
            print(len(indices), indices)
#     innerPath = np.concatenate([positions[yminIdx:],positions[:ymaxIdx+1]],axis=0) # inner path: [ymin:] + [:ymax+1]
#     outerPath = np.flip(positions[ymaxIdx:yminIdx+1],axis=0) # outer path: [ymax:ymin+1]

#     simpleInnerPath = np.array(simplifyPoints(innerPath,0,len(innerPath),epsilon)) # simplify inner
#     print('simpleInnerPath.shape',simpleInnerPath.shape)

#     # get matching simplified outer
#     simple_outer_x = np.interp(simpleInnerPath[:,1],outerPath[:,1],outerPath[:,0]).reshape([-1,1])
#     print('simple_outer_x',simple_outer_x[:5])
#     simple_outer_y = np.interp(simpleInnerPath[:,1],outerPath[:,1],outerPath[:,1]).reshape([-1,1])
#     print('simple_outer_y',simple_outer_y[:5])
#     simpleOuterPath = np.concatenate([simple_outer_x,simple_outer_y],axis=1)
#     print('simpleOuterPath.shape',simpleOuterPath.shape)

#     return simpleInnerPath, simpleOuterPath


########################################################################################


if __name__ == '__main__':
    from parse_svg_path import parse_svg_path
    example_svg = "m385,854c31,-1 67,-16 95,4c17,11 44,19 58,4c7,-26 -5,-49 -8,-75c-9,-30 -15,-62 -12,-94c-8,-29 -1,-61 2,-91c4,-28 21,-53 31,-80c5,-23 18,-43 33,-61c12,-24 23,-49 27,-76c3,-20 9,-44 1,-64c-13,-22 -39,-33 -54,-53c-16,-13 -38,-24 -30,-50c-15,-8 -42,-2 -25,17c3,33 39,43 58,65c23,20 27,53 26,82c-9,28 -21,56 -30,86c-17,30 -30,63 -48,94c-10,25 -18,52 -25,80c-5,28 3,56 8,84c7,29 9,60 17,89c4,17 0,46 -21,23c-16,-16 -45,-9 -65,-5c-12,12 -52,-4 -39,23"
    curve_points = parse_svg_path(example_svg)
    print('curve_points',len(curve_points),curve_points)
    line_segments = bezier_to_lineseg(curve_points, simplify_eps=0.0)
    print('line_segments',len(line_segments),line_segments)
    simplified_line_segments = bezier_to_lineseg(curve_points, simplify_eps=0.001)
    print('simplified_line_segments',len(simplified_line_segments),simplified_line_segments)
Exemplo n.º 5
0
def main(args):

    num_fracs = args.num_fracs
    random_seed = args.random_seed
    output_prefix = args.output_prefix
    user_shape = args.user_shape
    base_shape = args.base_shape
    rand_perturbation = args.rand_perturbation
    tolerance = args.tolerance
    simplify_eps = args.simplify_eps
    num_divisions = args.num_divisions
    cap_start = args.cap_start
    cap_end = args.cap_end
    use_map_xz = args.map_coords == 'xz'

    if user_shape is None:
        if 0 == base_shape:
            base_shape = np.random.randint(1, 4)
        if base_shape == 2:
            user_shape = svg_path_B
        elif base_shape == 3:
            user_shape = svg_path_C
        elif base_shape == 1:
            user_shape = svg_path_A
        else:  # random choice
            assert False
    else:
        base_shape = 0

    if 0 == random_seed:
        random_seed = np.random.randint(0, 1000000)
        print('random_seed auto generated', random_seed, file=sys.stderr)

    if rand_perturbation:
        rand_perturbation = np.random.randint(
            0, rand_perturbation * 10000) / 10000
        print('rand_perturbation will be used',
              rand_perturbation,
              file=sys.stderr)

    prefix = '{:s}_{:d}_{:d}_{:d}'.format(output_prefix, num_fracs, base_shape,
                                          random_seed)

    # create output directory if not exists
    output_dir = os.path.dirname(output_prefix)
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)

    # load svg path, extract curve points
    svg_path = normalize_svg(user_shape)

    with open(prefix + '_path.svg', 'w') as f:
        f.write(svg_path)

    # extract curve points from svg path
    curve_points = parse_svg_path(svg_path,
                                  rand_perturbation=rand_perturbation,
                                  rand_seed=random_seed)

    # convert curves to line segments
    points = bezier_to_lineseg(curve_points,
                               tolerance=tolerance,
                               simplify_eps=simplify_eps)
    # lathe line segments to build 3-d surface mesh
    nodes, texcoords, triangles = lathe_path(points,
                                             num_divisions=num_divisions,
                                             cap_start=cap_start,
                                             cap_end=cap_end,
                                             use_map_xz=use_map_xz)

    # make voronoi shatter pattern

    num_groups = num_fracs

    np.random.seed(random_seed)
    cells = np.random.uniform([0.0, 0.0], [1.0, 1.0], size=[num_groups, 2])

    if use_map_xz:
        voronoi = Voronoi(cells)
        voronoi_points = voronoi.points[:]
        voronoi_group = np.arange(len(voronoi_points))
    else:
        cells_mirrored = np.concatenate([
            cells,
            cells + [-1.0, 0.0],
            cells + [1.0, 0.0],
        ],
                                        axis=0)
        voronoi = Voronoi(cells_mirrored)
        voronoi_points = voronoi.points[:]
        voronoi_group = np.arange(len(voronoi_points))
        voronoi_group[num_groups:num_groups * 2] -= num_groups
        voronoi_group[num_groups * 2:] -= num_groups * 2

    shatter_filename = prefix + '.voronoi.json'
    voronoi_shatter = {
        'num_groups': num_groups,
        'point_group': voronoi_group.tolist(),
        'point': voronoi.points.tolist(),
    }
    with open(shatter_filename, 'w') as f:
        json.dump(voronoi_shatter, f)

    # create boundary markers for tetgen
    # markers are negative numbers <= -2
    vert_group = find_vertex_group(texcoords, voronoi_points, voronoi_group)
    face_group = find_element_group(triangles, texcoords, voronoi_points,
                                    voronoi_group)

    # create .smesh file to input to tetgen
    # put u, v coords into node attributes (#=2)
    # put group codes into vertice boundary markers, and into face boundary markers
    smesh_filename = prefix + '.smesh'
    with open(smesh_filename, 'w') as f:
        save_mesh(f,
                  nodes,
                  triangles,
                  node_attrs=texcoords,
                  node_boundary_markers=vert_group,
                  face_boundary_markers=face_group)

    # call `tetgen` executable to make 3-d mesh (delaunay tetrahedralization)
    tetgen_args = [
        "tetgen",
        "-p",
        smesh_filename,
    ]
    proc = subprocess.Popen(tetgen_args,
                            bufsize=0,
                            universal_newlines=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT)
    while True:
        line = proc.stdout.readline()
        if not line:
            break
        print(line.strip(), file=sys.stderr)

    tetgen_out_filebase = prefix + '.1'
    assert os.path.exists(tetgen_out_filebase + '.ele')

    # read generated object files (.ele, .face, .node)
    obj1 = load_tetgen(tetgen_out_filebase)

    # group 별로 파편 생성, 출력

    for i in range(num_fracs):
        part_name = prefix + '_part_{:d}'.format(i + 1)
        ptcloud_name = prefix + '_part_{:d}.npy'.format(i + 1)

        print('writing part', part_name, file=sys.stderr)

        sel = -(i + 2)

        new_obj, new_ptcloud = rebuild_submesh2(obj1, sel, voronoi_points,
                                                voronoi_group)
        new_obj.save(part_name)

        print('writing point-cloud', ptcloud_name, file=sys.stderr)

        with open(ptcloud_name, 'wb') as f:
            np.save(f, new_ptcloud)
        del new_obj
Exemplo n.º 6
0
import inspect

import sys, os.path
oldpath = sys.path
# inspect.stack()[0][1] is the full path to the current file.
sys.path.insert(0, os.path.dirname(inspect.stack()[0][1]))
import parse_svg_path
sys.path = oldpath

paths = parse_svg_path.parse_svg_path(
    '/home/mmccoo/kicad/kicad_mmccoo/svg2border/drawing.svg')

for path in paths:
    print("path {}".format(parse_svg_path.path_bbox(path)))
    #for poly in path.polys:
    #print("    points {}".format(poly))
    #print("        is hole {}".format(parse_svg_path.poly_is_hole(poly)))
    # print("    points 18{}".format(poly))
    for shape in path.group_by_bound_and_holes():
        print("bounds: {}".format(shape.bound))
        print("with holes:")
        for hole in shape.holes:
            print("   hole: {}".format(hole))
Exemplo n.º 7
0
if hasattr(pcbnew, "LAYER_ID_COUNT"):
    pcbnew.PCB_LAYER_ID_COUNT = pcbnew.LAYER_ID_COUNT

numlayers = pcbnew.PCB_LAYER_ID_COUNT
for i in range(numlayers):
    layertable[board.GetLayerName(i)] = i
    #print("{} {}".format(i, board.GetLayerName(i)))

# the internal coorinate space of pcbnew is 10E-6 mm. (a millionth of a mm)
# the coordinate 121550000 corresponds to 121.550000
SCALE = 1000000.0

powerlayer = layertable["B.Cu"]

# here I load from drawing.svg in the current directory. You'll want to change that path.
paths = parse_svg_path.parse_svg_path(
    os.path.dirname(inspect.stack()[0][1]) + '/drawing.svg')
if not paths:
    raise ValueError('wasnt able to read any paths from file')

# things are a little tricky below, because the first boundary has its first
# point passed into the creation of the new area. subsequent bounds are not
# done that way.
zone_container = None
shape_poly_set = None

for path in paths:
    for shape in path.group_by_bound_and_holes():
        shapeid = None
        if not shape_poly_set:
            # the call to GetNet() gets the netcode, an integer.
            zone_container = board.InsertArea(powernet.GetNet(), 0, powerlayer,