//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
RivCrossSectionPartMgr::RivCrossSectionPartMgr(const RimCrossSection* rimCrossSection)
    : m_rimCrossSection(rimCrossSection),
    m_defaultColor(cvf::Color3::WHITE)
{
    CVF_ASSERT(m_rimCrossSection);

    m_crossSectionFacesTextureCoords = new cvf::Vec2fArray;

    computeData();
}
Esempio n. 2
0
void MtlSaInverseBWTransform::doTransform(byte* bwt, uint32 bwt_size,
    const std::vector<uint32> &LFpowers) {
  PROFILE("MtlSaInverseBWTransform::doTransform");
  assert(bwt_size >= 2);
  assert(LFpowers.size() > 0);
  uint32 eob_position = LFpowers[0];

  // We use 'data' to store:
  //   a) LF^2[i] (4 bytes),
  //   b) a pair (bwt[LF[i]], bwt[i]) (2 bytes)
  // for each position i = 0, .., bwt_size - 1. In total the array takes roughly
  // 6 * bwt_size bytes. Having this array enables restoring the original string
  // two characters at a time.
  // Information a) and b) for position i is always accessed together. To reduce
  // the number of cache misses the following layout is used:
  //
  //   layout  | - - - - | - - | - - | - - - - | - - - - | - - | - - | - - - -|
  //   bytes        4       2     2       4         4       2     2       4
  //   meaning   LF^2[0]   P[0]  P[1]  LF^2[1]   LF^2[2]   P[2]  P[3]  LF^2[3]
  //
  // Where P[i] is a pair (bwt[LF[i]], bwt[i]).
  uint32 *data = new uint32[3 * ((bwt_size + 1) / 2)];
  computeData(bwt, bwt_size, data, eob_position);

  uint32 *data_ptr = &data[0];
  byte *result_ptr = bwt;
  uint32 starting_positions = LFpowers.size();
  uint32 block_size = bwt_size / starting_positions;
  uint32 to_restore = bwt_size - 1;

  // Stores the set of current LF powers (one per block).
  uint32 positions[starting_positions];
  std::copy(LFpowers.begin(), LFpowers.end(), positions);

  // If the block size is small, don't deploy parallel inversion.
  if (block_size <= 1) {
    starting_positions = 1;
    block_size = bwt_size;
  }

  // Stores pointers to positions in text that are about to be restored.
  uint16 *dest_ptr[starting_positions];
  for (uint32 i = 0; i < starting_positions; ++i) {
    dest_ptr[i] = (uint16 *)(result_ptr + i * block_size - 1);
  }

  // Restore the first pair from each block.
  for (uint32 block_id = 0; block_id < starting_positions; ++block_id) {
    uint32 position = positions[block_id];
    uint32 base = 3 * (position / 2);
    uint32 offset = position & 1;
    uint32 next_position = data_ptr[base + (offset << 1)];
    uint16 char_pair = ((uint16 *)(data_ptr + base + 1))[offset];
    positions[block_id] = next_position;
    if (block_id == 0) {
      // Skip the EOB symbol.
      ++dest_ptr[block_id];
      result_ptr[0] = ((unsigned char *)&char_pair)[1];
    } else { 
      // Not the first pair, decode as normal.
      *dest_ptr[block_id]++ = char_pair;
    }
  }

  // Restore the main part of each block, two characters at a time,
  // simultaneously from multiple starting positions.
  for (uint32 filled = 1; filled < block_size / 2; ++filled) {
    for (uint32 block_id = 0; block_id < starting_positions; ++block_id) {
      uint32 position = positions[block_id];
      uint32 base = 3 * (position / 2);
      uint32 offset = position & 1;
      uint32 next_position = data_ptr[base + (offset << 1)];
      uint16 char_pair = ((uint16 *)(data_ptr + base + 1))[offset];
      positions[block_id] = next_position;
      *dest_ptr[block_id]++ = char_pair;
    }
  }

  // If the block size is odd then there is one remaining character in each
  // block. This loop takes case of that. The last block is handled separately
  // because it might contain more than one remaining character.
  if (block_size & 1) {
    for (uint32 block_id = 0; block_id + 1 < starting_positions; ++block_id) {
      uint32 position = positions[block_id];
      uint32 base = 3 * (position / 2);
      uint32 offset = position & 1;
      uint16 char_pair = ((uint16 *)(data_ptr + base + 1))[offset];
      result_ptr[(block_id + 1) * block_size - 2] =
        ((unsigned char *)&char_pair)[0];
    }
  }

  // Restore the remaining characters from the last (longest) block,
  // possibly except the last character, if the last block has odd length.
  uint32 index = (starting_positions - 1) * block_size - 1 + 2 * (block_size / 2);
  while (index + 1 < to_restore) {
    uint32 position = positions[starting_positions - 1];
    uint32 base = 3 * (position / 2);
    uint32 offset = position & 1;
    uint32 next_position = data_ptr[base + (offset << 1)];
    uint16 char_pair = ((uint16 *)(data_ptr + base + 1))[offset];
    positions[starting_positions - 1] = next_position;
    *dest_ptr[starting_positions - 1]++ = char_pair;
    index += 2;
  }

  // Single character left in the last block.
  if (index != to_restore) {
    uint32 position = positions[starting_positions - 1];
    uint32 base = 3 * (position / 2);
    uint32 offset = position & 1;
    uint16 char_pair = ((uint16 *)(data_ptr + base + 1))[offset];
    result_ptr[to_restore - 1] = ((unsigned char *)&char_pair)[0];
  }

  delete[] data;
}