6#include <QtCore/QObject>
7#include <QtCore/QtAlgorithms>
8#include <QtCore/QVector>
32template <
class Position,
class Fulcrums>
154 typedef QVector<double> LayerPositions;
155 typedef QVector<LayerPositions> Layers;
164template <
class Position,
class Fulcrums>
168 return m_fulcrums.GetSizes();
172template <
class Position,
class Fulcrums>
175 return m_fulcrums.GetDimensionsCount();
179template <
class Position,
class Fulcrums>
182 Q_ASSERT(dimension >= 0);
183 Q_ASSERT(dimension <
int(m_layers.size()));
185 return m_layers[dimension].size();
189template <
class Position,
class Fulcrums>
192 Q_ASSERT(dimension >= 0);
193 Q_ASSERT(dimension <
int(m_layers.size()));
195 const LayerPositions& positions = m_layers[dimension];
197 Q_ASSERT(layerIndex >= 0);
198 Q_ASSERT(layerIndex <
int(positions.size()));
200 return positions[layerIndex];
206template <
class Position,
class Fulcrums>
209 m_layers.resize(m_fulcrums.GetDimensionsCount());
213template <
class Position,
class Fulcrums>
218 for (Layers::iterator iter = m_layers.begin(); iter != m_layers.end(); ++iter){
222 m_layers.resize(m_fulcrums.GetDimensionsCount());
226template <
class Position,
class Fulcrums>
229 if (m_fulcrums.SetDimensionsCount(count)){
230 m_layers.resize(count);
239template <
class Position,
class Fulcrums>
242 Q_ASSERT(dimension >= 0);
243 Q_ASSERT(dimension <
int(m_layers.size()));
245 m_layers[dimension].resize(count);
246 m_fulcrums.SetSize(dimension, count);
250template <
class Position,
class Fulcrums>
253 Q_ASSERT(dimension >= 0);
254 Q_ASSERT(dimension <
int(m_layers.size()));
256 LayerPositions& positions = m_layers[dimension];
258 Q_ASSERT(layerIndex >= 0);
259 Q_ASSERT(layerIndex <
int(positions.size()));
264 positions[layerIndex] = position;
268template <
class Position,
class Fulcrums>
271 int layersCount = int(m_layers.size());
272 Q_ASSERT(layersCount <= index.GetDimensionsCount());
274 result.SetElementsCount(layersCount);
276 for (
int i = 0; i < layersCount; ++i){
277 const LayerPositions& positions = m_layers[i];
279 Q_ASSERT(index[i] >= 0);
280 Q_ASSERT(index[i] <
int(positions.size()));
282 result[i] = positions[index[i]];
287template <
class Position,
class Fulcrums>
291 return m_fulcrums.GetAt(index);
295template <
class Position,
class Fulcrums>
300 m_fulcrums.SetAt(index, value);
304template <
class Position,
class Fulcrums>
307 Q_ASSERT(dimension >= 0);
308 Q_ASSERT(dimension < m_fulcrums.GetDimensionsCount());
310 Fulcrums newFulcrums = m_fulcrums;
312 newFulcrums.SetSize(dimension, m_fulcrums.GetSize(dimension) + 1);
314 int layerIndex = FindLayerIndex(dimension, position);
316 LayerPositions& positions = m_layers[dimension];
318 double prevPosition = position;
319 double nextPosition = position;
320 if (!positions.isEmpty()){
321 if (layerIndex >= 0){
322 prevPosition = positions[layerIndex];
324 if (layerIndex < GetLayersCount(dimension) - 1){
325 nextPosition = positions[layerIndex + 1];
328 Q_ASSERT(position >= prevPosition);
329 Q_ASSERT(position <= nextPosition);
331 double prevFactor = 0.5;
333 prevFactor = (position - prevPosition) / (nextPosition - prevPosition);
335 Q_ASSERT(prevFactor >= 0);
338 double nextFactor = 1 - prevFactor;
340 int oldLayersCount = int(positions.size());
341 Q_ASSERT(oldLayersCount == m_fulcrums.GetSize(dimension));
343 for (
typename Fulcrums::Iterator destIter = newFulcrums.Begin();
344 destIter != newFulcrums.End();
347 if ((destIter[dimension] >= layerIndex) && (sourceIndex[dimension] > 0)){
348 sourceIndex[dimension]--;
350 if ((destIter[dimension] == layerIndex) && (layerIndex < oldLayersCount)){
352 GetFulcrumPosition(sourceIndex, prevFulcrumPosition);
355 GetFulcrumPosition(destIter, nextFulcrumPosition);
357 PositionType position = prevFactor * prevFulcrumPosition + nextFactor * nextFulcrumPosition;
359 newFulcrums[destIter] = GetValueAt(position);
365 *destIter = m_fulcrums[sourceIndex];
368 positions.insert(positions.begin() + layerIndex + 1, position);
369 m_fulcrums = newFulcrums;
375template <
class Position,
class Fulcrums>
378 Q_ASSERT(dimension >= 0);
379 Q_ASSERT(dimension < GetDimensionsCount());
380 Q_ASSERT(m_fulcrums.GetSize(dimension) > 0);
382 Fulcrums newFulcrums = m_fulcrums;
384 newFulcrums.SetSize(dimension, m_fulcrums.GetSize(dimension) + 1);
386 LayerPositions& positions = m_layers[dimension];
388 for (
typename Fulcrums::Iterator destIter = newFulcrums.Begin();
389 destIter != newFulcrums.End();
392 if (destIter[dimension] >= layerIndex){
393 sourceIndex.IncreaseAt(dimension);
396 *destIter = m_fulcrums[sourceIndex];
399 positions.erase(positions.begin() + layerIndex);
400 m_fulcrums = newFulcrums;
406template <
class Position,
class Fulcrums>
421 int dimensionsCount = m_fulcrums.GetDimensionsCount();
422 Q_ASSERT(dimensionsCount ==
int(m_layers.size()));
424 retVal = retVal && archive.
BeginMultiTag(gridTag, positionsTag, dimensionsCount);
426 if (!isStoring && (dimensionsCount != m_fulcrums.GetDimensionsCount())){
427 if (!SetDimensionsCount(dimensionsCount)){
433 Q_ASSERT(sizes.GetDimensionsCount() >= dimensionsCount);
435 for (
int dimensionIndex = 0; dimensionIndex < dimensionsCount; ++dimensionIndex){
436 LayerPositions& positions = m_layers[dimensionIndex];
438 int& positionsCount = sizes[dimensionIndex];
439 Q_ASSERT(positionsCount ==
int(positions.size()));
441 retVal = retVal && archive.
BeginMultiTag(positionsTag, positionTag, positionsCount);
450 SetLayersCount(dimensionIndex, positionsCount);
453 for (
int positionIndex = 0; positionIndex < positionsCount; ++positionIndex){
454 retVal = retVal && archive.
BeginTag(positionTag);
455 retVal = retVal && archive.
Process(positions[positionIndex]);
456 retVal = retVal && archive.
EndTag(positionTag);
459 retVal = retVal && archive.
EndTag(positionsTag);
462 retVal = retVal && archive.
EndTag(gridTag);
464 retVal = retVal && archive.
BeginTag(fulcrumsTag);
466 for (
typename Fulcrums::Iterator iter = m_fulcrums.Begin();
467 iter != m_fulcrums.End();
471 retVal = retVal && archive.
BeginTag(fulcrumTag);
472 retVal = retVal && point.Serialize(archive);
473 retVal = retVal && archive.
EndTag(fulcrumTag);
476 retVal = retVal && archive.
EndTag(fulcrumsTag);
484template <
class Position,
class Fulcrums>
487 return (m_fulcrums == value.m_fulcrums) && (m_layers == value.m_layers);
491template <
class Position,
class Fulcrums>
494 return (m_fulcrums != value.m_fulcrums) || (m_layers != value.m_layers);
500template <
class Position,
class Fulcrums>
503 for (Layers::iterator iter = m_layers.begin(); iter != m_layers.end(); ++iter){
504 LayerPositions& positions = *iter;
506 qSort(positions.begin(), positions.end());
511template <
class Position,
class Fulcrums>
514 Q_ASSERT(dimension >= 0);
515 Q_ASSERT(dimension < GetDimensionsCount());
517 const LayerPositions& positions = m_layers[dimension];
520 int right = int(positions.size());
522 while (left != right){
523 int center = (left + right) / 2;
525 if (value >= positions[center]){
537template <
class Position,
class Fulcrums>
538typename Fulcrums::IndexType
541 int dimensionsCount = GetDimensionsCount();
545 for (
int i = 0; i < dimensionsCount; ++i){
546 retVal[i] = FindLayerIndex(i, argument[i]);
555template <
class Position,
class Fulcrums>
Representation of fulcrums in multi-dimesional regular grid.
virtual bool SetDimensionsCount(int count)
Set number of dimensions.
void Reset()
Removes all fulcrum points.
virtual void SetFulcrumAtIndex(const FulcrumIndex &index, const FulcrumType &value)
Set single fulcrum point.
virtual void SetLayerPosition(int dimension, int layerIndex, double position)
Set position of specified layer of fulcrums.
int InsertLayer(int dimension, double position)
Inserts single fulcrum layer.
virtual bool Serialize(iser::IArchive &archive) override
Load or store state of this object as a archive stream.
const FulcrumType & GetFulcrumAtIndex(const FulcrumIndex &index) const
Get value at specified index.
double GetLayerPosition(int dimension, int layerIndex) const
Get position of specified layer of fulcrums.
Fulcrums::IndexType FindIndices(const PositionType &argument) const
Find indices of cuboid containing specified argument value.
FulcrumSizes GetGridSize() const
Return complete grid size.
int GetDimensionsCount() const
Get number of dimensions.
Fulcrums::IndexType FulcrumIndex
Fulcrums::SizesType FulcrumSizes
static const ChangeSet s_fulcrumPositionChange
virtual void SetLayersCount(int dimension, int count)
Set number of fulcrum layers at specified dimension.
ChangeFlags
Data model change notification flags.
virtual void SortFulcrums()
Sort fulcrums in this collection.
bool operator!=(const TFulcrumGrid< Position, Fulcrums > &value) const
int GetLayersCount(int dimension) const
Get number of fulcrum points used in this function.
bool operator==(const TFulcrumGrid< Position, Fulcrums > &value) const
Fulcrums::ElementType FulcrumType
int FindLayerIndex(int dimension, double value) const
Find layer index of specified value for specified dimension.
virtual void RemoveLayer(int dimension, int layerIndex)
Remove fulcrums at spacified layer.
void GetFulcrumPosition(const FulcrumIndex &index, PositionType &result) const
Get position of node at specified grid index.
Process tag used to group data in archive stream.
@ TT_GROUP
Normal tag used for grouping of tags or processed elements.
@ TT_LEAF
Leaf tag, it can contain only one primitive element.
@ TT_MULTIPLE
Multiple tag containing variable number of child tags.
Represents an input/output persistence archive for object serialization.
virtual bool Process(bool &value)=0
Processes (reads or writes) a boolean value.
virtual bool EndTag(const CArchiveTag &tag)=0
Ends a tagged section in the archive.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begins a tagged section containing multiple elements of the same type.
virtual bool IsStoring() const =0
Checks if this archive is in storing (writing) or loading (reading) mode.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begins a tagged section in the archive.
Common class for all classes which objects can be archived or restored from archive.
Help class which provides the automatic update mechanism of the model.
Set of change flags (its IDs).
#define I_EPSILON
Some very small number.
static const double I_BIG_EPSILON
Package with mathematical functions and algebraical primitives.