|
| 1 | +import pyvcad as pv |
| 2 | +import pyvcad_rendering as viz |
| 3 | + |
| 4 | +def make_checkerboard( |
| 5 | + center: pv.Vec3, |
| 6 | + total_size_xy: pv.Vec3, # only x,y used; z ignored here |
| 7 | + tiles_x: int, |
| 8 | + tiles_y: int, |
| 9 | + tile_height: float, |
| 10 | + white_name: str = "white", |
| 11 | + black_name: str = "black", |
| 12 | + start_white_at_lower_left: bool = True |
| 13 | +) -> pv.Union: |
| 14 | + """ |
| 15 | + Build a single-layer checkerboard of RectPrism tiles. |
| 16 | + - center: board center in 3D (z is the board mid-plane) |
| 17 | + - total_size_xy: overall X/Y size (use pv.Vec3(w, h, 0) or pv.Vec3(w,h,any)) |
| 18 | + - tiles_x / tiles_y: number of tiles along X and Y |
| 19 | + - tile_height: thickness in Z for each cube/tile |
| 20 | + """ |
| 21 | + |
| 22 | + materials = pv.default_materials |
| 23 | + mat_white = materials.id(white_name) |
| 24 | + mat_black = materials.id(black_name) |
| 25 | + |
| 26 | + union = pv.Union() |
| 27 | + |
| 28 | + board_w = float(total_size_xy.x) |
| 29 | + board_h = float(total_size_xy.y) |
| 30 | + tile_w = board_w / tiles_x |
| 31 | + tile_h = board_h / tiles_y |
| 32 | + |
| 33 | + # min corner of the board (lower-left in XY) at z centered |
| 34 | + min_x = center.x - board_w * 0.5 |
| 35 | + min_y = center.y - board_h * 0.5 |
| 36 | + cz = center.z # mid-plane |
| 37 | + |
| 38 | + # Decide the color parity of the (0,0) tile (lower-left) |
| 39 | + base_white = 0 if start_white_at_lower_left else 1 |
| 40 | + |
| 41 | + for ix in range(tiles_x): |
| 42 | + for iy in range(tiles_y): |
| 43 | + # tile center |
| 44 | + cx = min_x + (ix + 0.5) * tile_w |
| 45 | + cy = min_y + (iy + 0.5) * tile_h |
| 46 | + |
| 47 | + # alternating material |
| 48 | + parity = (ix + iy + base_white) % 2 |
| 49 | + mat = mat_white if parity == 0 else mat_black |
| 50 | + |
| 51 | + # build cube (rectangular prism) for this tile |
| 52 | + size = pv.Vec3(tile_w, tile_h, tile_height) |
| 53 | + center_pt = pv.Vec3(cx, cy, cz) |
| 54 | + tile = pv.RectPrism(center_pt, size, mat) |
| 55 | + union.add_child(tile) |
| 56 | + |
| 57 | + return union |
| 58 | + |
| 59 | + |
| 60 | +# ------------------------- |
| 61 | +# Example usage |
| 62 | +# ------------------------- |
| 63 | +materials = pv.default_materials |
| 64 | +white = materials.id("white") |
| 65 | +black = materials.id("black") |
| 66 | +green = materials.id("green") |
| 67 | + |
| 68 | +checker = make_checkerboard( |
| 69 | + center=pv.Vec3(0, 0, 0), |
| 70 | + total_size_xy=pv.Vec3(225, 225, 0), |
| 71 | + tiles_x=10, |
| 72 | + tiles_y=10, |
| 73 | + tile_height=5.0, |
| 74 | + white_name="white", |
| 75 | + black_name="black", |
| 76 | + start_white_at_lower_left=True |
| 77 | +) |
| 78 | + |
| 79 | + |
| 80 | +size = pv.Vec3(225,225,20) |
| 81 | +unit_cell_size = pv.Vec3(7,7,7) |
| 82 | +strut_diameter = 0.55 |
| 83 | +cell_bcc = pv.GraphLattice(pv.LatticeType.BodyCenteredCubic, unit_cell_size, strut_diameter, 1) |
| 84 | +lattice_fill = pv.Tile(cell_bcc) |
| 85 | +rect_prism = pv.RectPrism(pv.Vec3(0,0,0), size) |
| 86 | +filled_rect_prism = pv.Intersection(False, [lattice_fill, rect_prism]) |
| 87 | + |
| 88 | +object_to_wrap = checker |
| 89 | + |
| 90 | +base_surface = pv.Sphere(pv.Vec3(0, 0, 0), 100.0, green) |
| 91 | +conformal = pv.ConformalMap() |
| 92 | +conformal.set_left(base_surface) |
| 93 | +conformal.set_right(object_to_wrap) |
| 94 | + |
| 95 | +union = pv.Union() |
| 96 | +union.add_child(conformal) |
| 97 | +union.add_child(base_surface) |
| 98 | + |
| 99 | +root = union |
| 100 | + |
| 101 | +viz.Render(root, materials) |
0 commit comments