code: def voxelize(obj, **kwargs):
      
      # Get keyword arguments
      grid_size = kwargs.pop('grid_size', (8, 8, 8))
      use_cubes = kwargs.pop('use_cubes', False)
      num_procs = kwargs.get('num_procs', 1)
  
      if not isinstance(grid_size, (list, tuple)):
          raise TypeError("Grid size must be a list or a tuple of integers")
  
      # Initialize result arrays
      grid = []
      filled = []
  
      # Should also work with multi surfaces and volumes
      for o in obj:
          # Generate voxel grid
          grid_temp = vxl.generate_voxel_grid(o.bbox, grid_size, use_cubes=use_cubes)
          args = [grid_temp, o.evalpts]
  
          # Find in-outs
          filled_temp = vxl.find_inouts_mp(*args, **kwargs) if num_procs > 1 else vxl.find_inouts_st(*args, **kwargs)
  
          # Add to result arrays
          grid += grid_temp
          filled += filled_temp
  
      # Return result arrays
      return grid, filled
docs: Generates binary voxel representation of the surfaces and volumes.
  
      Keyword Arguments:
          * ``grid_size``: size of the voxel grid. *Default: (8, 8, 8)*
          * ``padding``: voxel padding for in-outs finding. *Default: 10e-8*
          * ``use_cubes``: use cube voxels instead of cuboid ones. *Default: False*
          * ``num_procs``: number of concurrent processes for voxelization. *Default: 1*
  
      :param obj: input surface(s) or volume(s)
      :type obj: abstract.Surface or abstract.Volume
      :return: voxel grid and filled information
      :rtype: tuple