mikepound / opencubes

A community improved version of the polycubes project!
MIT License
45 stars 23 forks source link

Add Python Support for .pcube file format #17

Closed bertie2 closed 1 year ago

bertie2 commented 1 year ago

Add a converter tool to convert to and from .pcube file format to and from .npy. this format is also supported by the rust implementation so this would make the two compatible.

format specification:

extension : .pcube
data: binary
header:
[4 bytes] [byte]      [byte]      [bytes...] [bytes...]
magic     orientation compression cube_count body

  [4 bytes] magic:
    for uniquely identifying this format, takes the raw hex value
    0xCBECCBEC

  [byte] orientation:
    allows for different future canonical orientations current options are:
      0 : UNSORTED : these are random rotations rotate them yourself to get whatever your canonical rotations are.
      1 : BITWISE_HIGHEST_VALUE: the rotation of the cube which has the highest value when compared byte by byte in the cube format (see body format for details):
    more orientations can be added if better methods for finding identical rotations are found.

  [byte] compression:
    indicates whether the body data is compressed:
      0: uncompressed data stream
      1: gzip compressed data stream

  [bytes...] cube_count:
    a LEB128 encoded arbitrarily large unsigned integer representing the number of cubes in this file / stream (https://en.wikipedia.org/wiki/LEB128).
    0 indicates that this is a variable length file / stream and will simply abruptly end.

  [bytes...] body:
   a set of data blocks for each cube where each block takes the form:
      x     y     z     data
      [byte][byte][byte][bytes...]

      [byte] x:
        an 8 bit unsigned integer representing the cubes x dimension
      [byte] y:
        an 8 bit unsigned integer representing the cubes x dimension
      [byte] z:
        an 8 bit unsigned integer representing the cubes x dimension
      [bytes...] data:
        the flattened bits of the polycube where 1 is a filled space and 0 is empty, flattened in row-major (C-style), stored in little endian, padded to the nearest byte with zeros.

I think its also worth changing over the base application cubes.py to use this file format as it is significantly smaller. but didn't want to initially include it here until the format and converter where reviewed.