VolumeDataRegion.cpp 5.68 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/

#include "VolumeDataRegion.h"

#include "VolumeDataChunk.h"
#include "VolumeDataLayout.h"

#include <assert.h>
#include <algorithm>

namespace OpenVDS
{
Jørgen Lind's avatar
Jørgen Lind committed
28
int64_t VolumeDataRegion::getNumChunksInRegion() const
29
30
31
32
{
  return m_chunksInRegion;
}

Jørgen Lind's avatar
Jørgen Lind committed
33
int64_t VolumeDataRegion::getChunkIndexInRegion(int64_t chunkInRegion) const
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
  assert(chunkInRegion >= 0 && chunkInRegion < m_chunksInRegion);

  int64_t iChunkIndex = 0;

  for(int32_t iDimension = int32_t(array_size(m_chunkMin)) - 1; iDimension >= 0; iDimension--)
  {
    iChunkIndex += (chunkInRegion / m_modulo[iDimension] + m_chunkMin[iDimension]) * m_layerModulo[iDimension];
    chunkInRegion %= m_modulo[iDimension];
  }

  return iChunkIndex;
}

Jørgen Lind's avatar
Jørgen Lind committed
48
void VolumeDataRegion::getChunksInRegion(std::vector<VolumeDataChunk>* volumeDataChunk, bool isAppend) const
49
50
51
52
53
54
{
  if (!isAppend)
  {
    volumeDataChunk->clear();
  }

Jørgen Lind's avatar
Jørgen Lind committed
55
  int32_t nChunksInRegion = (int32_t)getNumChunksInRegion();
56
57
58
59
60
61
  if(!nChunksInRegion) return;

  volumeDataChunk->reserve(nChunksInRegion);

  for(int32_t iChunkInRegion = 0; iChunkInRegion < nChunksInRegion; iChunkInRegion++)
  {
Jørgen Lind's avatar
Jørgen Lind committed
62
    volumeDataChunk->push_back(m_volumeDataLayer->getChunkFromIndex(getChunkIndexInRegion(iChunkInRegion)));
63
64
65
  }
}

Jørgen Lind's avatar
Jørgen Lind committed
66
bool VolumeDataRegion::isChunkInRegion(VolumeDataChunk const &volumeDataChunk) const
67
68
69
70
71
72
{
  if(//volumeDataChunk.GetVDS() == _gVDS &&
     volumeDataChunk.layer == m_volumeDataLayer)
  {
    IndexArray indexArray;

Jørgen Lind's avatar
Jørgen Lind committed
73
    m_volumeDataLayer->chunkIndexToIndexArray(volumeDataChunk.chunkIndex, indexArray);
74
75
76
77
78
79
80
81
82
83
84
85
86
    for(int32_t iDimension = 0; iDimension < array_size(indexArray); iDimension++)
    {
      if(indexArray[iDimension] < m_chunkMin[iDimension] ||
         indexArray[iDimension] > m_chunkMax[iDimension])
      {
        return false;
      }
    }
    return true;
  }
  return false;
}

Jørgen Lind's avatar
Jørgen Lind committed
87
VolumeDataRegion::VolumeDataRegion(VolumeDataLayer const &volumeDataLayer, const IndexArray &min, const IndexArray &max)
88
89
  : m_volumeDataLayer(&volumeDataLayer)
{
Jørgen Lind's avatar
Jørgen Lind committed
90
  VolumeDataLayout *volumeDataLayout = volumeDataLayer.getLayout();
91

Jørgen Lind's avatar
Jørgen Lind committed
92
  int64_t modulo = 1;
93
94
95

  for(int32_t iDimension = 0; iDimension < array_size(m_chunkMin); iDimension++)
  {
Jørgen Lind's avatar
Jørgen Lind committed
96
97
    m_chunkMin[iDimension] = volumeDataLayer.voxelToIndex(min[iDimension], iDimension);
    m_chunkMax[iDimension] = volumeDataLayer.voxelToIndex(max[iDimension] - 1, iDimension);
98
99

    m_layerModulo[iDimension] = volumeDataLayer.m_modulo[iDimension];
Jørgen Lind's avatar
Jørgen Lind committed
100
101
    m_modulo[iDimension] = modulo;
    modulo *= m_chunkMax[iDimension] - m_chunkMin[iDimension] + 1;
102
103
104
105

    assert(m_chunkMin[iDimension] <= m_chunkMax[iDimension]);
  }

Jørgen Lind's avatar
Jørgen Lind committed
106
  m_chunksInRegion = modulo;
107
108
}

Jørgen Lind's avatar
Jørgen Lind committed
109
VolumeDataRegion VolumeDataRegion::VolumeDataRegionOverlappingChunk(VolumeDataLayer const &volumeDataLayer, VolumeDataChunk const &volumeDataChunk, const IndexArray &offset)
110
111
112
113
114
115
{
  IndexArray min;
  IndexArray max;

  const VolumeDataLayer *targetLayer = volumeDataChunk.layer;

Jørgen Lind's avatar
Jørgen Lind committed
116
  assert(volumeDataLayer.getVolumeDataChannelMapping() == targetLayer->getVolumeDataChannelMapping() && "VolumeDataRegionOverlappingChunk() doesn't work between layers with different mappings");
117

Jørgen Lind's avatar
Jørgen Lind committed
118
  targetLayer->getChunkMinMax(volumeDataChunk.chunkIndex, min, max, false);
119
120
121
122
123
124
125
126
127

  IndexArray validMin;
  IndexArray validMax;

  for(int32_t iDimension = 0; iDimension < array_size(validMin); iDimension++)
  {
    int32_t nNeededExtraValidVoxelsNegative = 0;
    int32_t nNeededExtraValidVoxelsPositive = 0;

Jørgen Lind's avatar
Jørgen Lind committed
128
    if(DimensionGroupUtil::isDimensionInGroup(targetLayer->m_originalDimensionGroup, iDimension))
129
    {
Jørgen Lind's avatar
Jørgen Lind committed
130
131
      nNeededExtraValidVoxelsNegative += volumeDataLayer.getNegativeRenderMargin();
      nNeededExtraValidVoxelsPositive += volumeDataLayer.getPositiveRenderMargin();
132

Jørgen Lind's avatar
Jørgen Lind committed
133
      if(DimensionGroupUtil::isDimensionInGroup(volumeDataLayer.getOriginalDimensionGroup(), iDimension))
134
135
      {
        // How much can we copy from render margin to render margin?
Jørgen Lind's avatar
Jørgen Lind committed
136
137
        nNeededExtraValidVoxelsNegative -= volumeDataLayer.getNegativeRenderMargin();
        nNeededExtraValidVoxelsPositive -= volumeDataLayer.getPositiveRenderMargin();
138
139
140
      }
    }

Jørgen Lind's avatar
Jørgen Lind committed
141
142
143
    nNeededExtraValidVoxelsNegative += targetLayer->getNegativeMargin(iDimension) - volumeDataLayer.getNegativeMargin(iDimension);
    nNeededExtraValidVoxelsNegative += targetLayer->getNegativeMargin(iDimension) - volumeDataLayer.getNegativeMargin(iDimension);
    nNeededExtraValidVoxelsPositive += targetLayer->getPositiveMargin(iDimension) - volumeDataLayer.getPositiveMargin(iDimension);
144

Jørgen Lind's avatar
Jørgen Lind committed
145
146
    validMin[iDimension] = min[iDimension] - offset[iDimension] - std::max(0, nNeededExtraValidVoxelsNegative),
    validMax[iDimension] = max[iDimension] - offset[iDimension] + std::max(0, nNeededExtraValidVoxelsPositive);
147
148

    // Limit the valid area so it doesn't extend into the border
Jørgen Lind's avatar
Jørgen Lind committed
149
150
    validMin[iDimension] = std::max(validMin[iDimension], targetLayer->getDimensionFirstSample(iDimension));
    validMax[iDimension] = std::min(validMax[iDimension], targetLayer->getDimensionFirstSample(iDimension) + targetLayer->getDimensionNumSamples(iDimension));
151
152
153
154
155
156
  }

  return VolumeDataRegion(volumeDataLayer, validMin, validMax);
}

}