def __init__(self, bounds, plate_height_ratio, height): self.bounds = bounds self.plate_scale_real = Point( [unit_distance, unit_distance * plate_height_ratio, unit_distance]) self.ratio = Point([plate_height_ratio, 1, plate_height_ratio]) self.scale = (height / bounds.range_.y) * self.ratio self.grid_dimensions = Point.as_int(np.ceil(self.scale * bounds.range_))
def get_bricks_by_layer(self): xdim, ydim, zdim = self.shape grid_iter_by_y_layer = it.product(*(range(dim) for dim in (ydim, zdim, xdim))) bricks_by_layer_asc = (Point.as_int((x, y, z)) for (y, z, x) in grid_iter_by_y_layer if self[(x, y, z)]) return bricks_by_layer_asc
def to_blocks(scaling, face, jitter): blocks = [scaling.to_grid_point(fc) for fc in face] bounds = np.min(blocks, axis=0), np.max(blocks, axis=0) + 1 grid_dim_real = jitter * (scaling.bounds.range_ / scaling.grid_dimensions) ranges = [range(lo, hi) for lo, hi in zip(*bounds)] vertices = len(face) for i in range(vertices - 2): triangle = np.take(face, [j % vertices for j in range(i, i + 3)], axis=0) for block in (Point.as_int(block) for block in it.product(*ranges)): block_center_real = scaling.to_world_point(block + 0.5) if intersects_box(triangle, block_center_real, grid_dim_real): yield block
def to_grid_point(self, world_point): val = self.scale_down(world_point - self.bounds.lo) grid_index = (0, 0, 0), self.grid_dimensions - 1 return Point.as_int(np.clip(np.round(val), *grid_index))