/**************************************************************************** Copyright (C) 2010-2012 the Office National des Forets (ONF), France and the Association de Recherche Technologie et Sciences (ARTS), Ecole Nationale Suprieure d'Arts et Métiers (ENSAM), Cluny, France. All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Alexandre PIBOULE (ONF) This file is part of PluginShared library 2.0. PluginShared is free library: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PluginShared is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PluginShared. If not, see . *****************************************************************************/ #ifndef CT_GRID3D_HPP #define CT_GRID3D_HPP #include "ct_itemdrawable/ct_grid3d.h" #include "ct_itemdrawable/tools/drawmanager/ct_standardgrid3ddrawmanager.h" #include #include #include #include "ct_math/ct_math.h" #include "qdebug.h" template< typename DataT> const CT_StandardGrid3DDrawManager CT_Grid3D::ABSGRID3D_DRAW_MANAGER; template< typename DataT> CT_Grid3D::CT_Grid3D() : CT_AbstractGrid3D() { _minCoordinates(0) = 0; _minCoordinates(1) = 0; _minCoordinates(2) = 0; _res = 1; _dimx = 0; _dimy = 0; _dimz = 0; _maxCoordinates(0) = 0; _maxCoordinates(1) = 0; _maxCoordinates(2) = 0; _NAdata = -1; _dataMax = -1; _dataMin = -1; setBaseDrawManager(&ABSGRID3D_DRAW_MANAGER); } template< typename DataT> CT_Grid3D::CT_Grid3D(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, double xmin, double ymin, double zmin, size_t dimx, size_t dimy, size_t dimz, double resolution, DataT na, DataT initValue) : CT_AbstractGrid3D(model, result) { _minCoordinates(0) = xmin; _minCoordinates(1) = ymin; _minCoordinates(2) = zmin; _res = resolution; _dimx = dimx; _dimy = dimy; _dimz = dimz; _maxCoordinates(0) = minX() + _res * _dimx; _maxCoordinates(1) = minY() + _res * _dimy; _maxCoordinates(2) = minZ() + _res * _dimz; _NAdata = na; setCenterX (minX() + (maxX() - minX())/2.0); setCenterY (minY() + (maxY() - minY())/2.0); setCenterZ (minZ() + (maxZ() - minZ())/2.0); _data.resize(nCells()); initGridWithValue(initValue); setBaseDrawManager(&ABSGRID3D_DRAW_MANAGER); } template< typename DataT> CT_Grid3D::CT_Grid3D(const QString &modelName, const CT_AbstractResult *result, double xmin, double ymin, double zmin, size_t dimx, size_t dimy, size_t dimz, double resolution, DataT na, DataT initValue) : CT_AbstractGrid3D(modelName, result) { _minCoordinates(0) = xmin; _minCoordinates(1) = ymin; _minCoordinates(2) = zmin; _res = resolution; _dimx = dimx; _dimy = dimy; _dimz = dimz; _maxCoordinates(0) = minX() + _res * _dimx; _maxCoordinates(1) = minY() + _res * _dimy; _maxCoordinates(2) = minZ() + _res * _dimz; _NAdata = na; setCenterX (minX() + (maxX() - minX())/2.0); setCenterY (minY() + (maxY() - minY())/2.0); setCenterZ (minZ() + (maxZ() - minZ())/2.0); _data.resize(nCells()); initGridWithValue(initValue); setBaseDrawManager(&ABSGRID3D_DRAW_MANAGER); } template< typename DataT> CT_Grid3D::CT_Grid3D(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, double resolution, DataT na, DataT initValue) : CT_AbstractGrid3D(model, result) { _minCoordinates(0) = (xmin); _minCoordinates(1) = (ymin); _minCoordinates(2) = (zmin); _res = resolution; _dimx = ceil((xmax - xmin)/_res); _dimy = ceil((ymax - ymin)/_res); _dimz = ceil((zmax - zmin)/_res); _maxCoordinates(0) = (minX() + _res * _dimx); _maxCoordinates(1) = (minY() + _res * _dimy); _maxCoordinates(2) = (minZ() + _res * _dimz); _NAdata = na; // to ensure a point exactly on a maximum limit of the grid will be included in the grid while (xmax >= maxX()) { _dimx++; _maxCoordinates(0) = (maxX() + _res); } while (ymax >= maxY()) { _dimy++; _maxCoordinates(1) = (maxY() + _res); } while (zmax >= maxZ()) { _dimz++; _maxCoordinates(2) = (maxZ() + _res); } setCenterX (minX() + (maxX() - minX())/2.0); setCenterY (minY() + (maxY() - minY())/2.0); setCenterZ (minZ() + (maxZ() - minZ())/2.0); _data.resize(nCells()); initGridWithValue(initValue); setBaseDrawManager(&ABSGRID3D_DRAW_MANAGER); } template< typename DataT> CT_Grid3D::CT_Grid3D(const QString& model, const CT_AbstractResult *result, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, double resolution, DataT na, DataT initValue) : CT_AbstractGrid3D(model, result) { _minCoordinates(0) = (xmin); _minCoordinates(1) = (ymin); _minCoordinates(2) = (zmin); _res = resolution; _dimx = ceil((xmax - xmin)/_res); _dimy = ceil((ymax - ymin)/_res); _dimz = ceil((zmax - zmin)/_res); _maxCoordinates(0) = (minX() + _res * _dimx); _maxCoordinates(1) = (minY() + _res * _dimy); _maxCoordinates(2) = (minZ() + _res * _dimz); _NAdata = na; // to ensure a point exactly on a maximum limit of the grid will be included in the grid while (xmax >= maxX()) { _dimx++; _maxCoordinates(0) = (maxX() + _res); } while (ymax >= maxY()) { _dimy++; _maxCoordinates(1) = (maxY() + _res); } while (zmax >= maxZ()) { _dimz++; _maxCoordinates(2) = (maxZ() + _res); } setCenterX (minX() + (maxX() - minX())/2.0); setCenterY (minY() + (maxY() - minY())/2.0); setCenterZ (minZ() + (maxZ() - minZ())/2.0); _data.resize(nCells()); initGridWithValue(initValue); setBaseDrawManager(&ABSGRID3D_DRAW_MANAGER); } template< typename DataT> CT_Grid3D* CT_Grid3D::createGrid3DFromXYZCoords(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, double resolution, DataT na, DataT initValue, bool extends) { size_t dimx = ceil((xmax - xmin)/resolution); size_t dimy = ceil((ymax - ymin)/resolution); size_t dimz = ceil((zmax - zmin)/resolution); if (extends) { // to ensure a point exactly on a maximum limit of the grid will be included in the grid while (xmax >= (xmin + dimx * resolution)) { dimx++; } while (ymax >= (ymin + dimy * resolution)) { dimy++; } while (zmax >= (zmin + dimz * resolution)) { dimz++; } } return new CT_Grid3D(model, result, xmin, ymin, zmin, dimx, dimy, dimz, resolution, na, initValue); } template< typename DataT> CT_Grid3D* CT_Grid3D::createGrid3DFromXYZCoords(const QString &modelName, const CT_AbstractResult *result, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, double resolution, DataT na, DataT initValue, bool extends) { size_t dimx = ceil((xmax - xmin)/resolution); size_t dimy = ceil((ymax - ymin)/resolution); size_t dimz = ceil((zmax - zmin)/resolution); if (extends) { // to ensure a point exactly on a maximum limit of the grid will be included in the grid while (xmax >= (xmin + dimx * resolution)) { dimx++; } while (ymax >= (ymin + dimy * resolution)) { dimy++; } while (zmax >= (zmin + dimz * resolution)) { dimz++; } } return new CT_Grid3D(modelName, result, xmin, ymin, zmin, dimx, dimy, dimz, resolution, na, initValue); } template< typename DataT> CT_Grid3D::~CT_Grid3D() { _data.clear(); } template< typename DataT> void CT_Grid3D::initGridWithValue(const DataT val) { for (size_t i = 0 ; i < nCells() ; i++) { _data[i] = val; } _dataMin = val; _dataMax = val; } template< typename DataT> void CT_Grid3D::setValueAtIndexFromDouble(const size_t &index, const double &value) { setValueAtIndex(index, (DataT) value); } template< typename DataT> void CT_Grid3D::computeMinMax() { size_t ncells = nCells(); if (ncells > 0) { _dataMin = _data[0]; _dataMax = _data[0]; for (size_t i = 1 ; i < ncells ; i++) { if (_data[i] != NA()) { if (_dataMax==NA() || _data[i] > _dataMax) {_dataMax = _data[i];} if (_dataMin==NA() || _data[i] < _dataMin) {_dataMin = _data[i];} } } } } template< typename DataT> QString CT_Grid3D::getType() const { return staticGetType(); } template< typename DataT> QString CT_Grid3D::staticGetType() { QString type = CT_AbstractGrid3D::staticGetType() + "/CT_Grid3D<" + CT_TypeInfo::name() + ">"; CT_AbstractItemDrawable::addNameTypeCorresp(type, staticName()); return type; } template< typename DataT> QString CT_Grid3D::name() const { return staticName(); } template< typename DataT> QString CT_Grid3D::staticName() { return tr("3D grid<%1>").arg(CT_TypeInfo::name()); } template< typename DataT> bool CT_Grid3D::setValueAtIndex(const size_t index, const DataT value) { if (index >= nCells()) {return false;} _data[index] = value; return true; } template< typename DataT> bool CT_Grid3D::setValue(const size_t colx, const size_t liny, const size_t levz, const DataT value) { size_t i; if (index(colx, liny, levz, i)) { return setValueAtIndex(i, value); } return false; } template< typename DataT> bool CT_Grid3D::setValueAtXYZ(const double x, const double y, const double z, const DataT value) { size_t i; if (indexAtXYZ(x, y, z, i)) { return setValueAtIndex(i, value); } return false; } template< typename DataT> DataT CT_Grid3D::valueAtIndex(const size_t index) const { if (index >= nCells()) {return NA();} return _data[index]; } template< typename DataT> double CT_Grid3D::ratioValueAtIndex(const size_t index) const { if (_dataMax <= _dataMin) {return 1;} DataT value = valueAtIndex(index); if (value == NA()) {return -1;} return (double) (((double)(value - _dataMin))/((double)(_dataMax - _dataMin))); } template< typename DataT> double CT_Grid3D::valueAtIndexAsDouble(const size_t index) const { DataT value = valueAtIndex(index); if (value == NA()) {return std::numeric_limits::quiet_NaN();} return value; } template< typename DataT> QString CT_Grid3D::valueAtIndexAsString(const size_t index) const { DataT value = valueAtIndex(index); return QVariant(value).toString(); } template< typename DataT> QString CT_Grid3D::NAAsString() const { return QVariant(NA()).toString(); } template< typename DataT> DataT CT_Grid3D::value(const size_t colx, const size_t liny, const size_t levz) const { size_t i; if (index(colx, liny, levz, i)) { return valueAtIndex(i); } return NA(); } template< typename DataT> DataT CT_Grid3D::dataFromArray(const size_t &x, const size_t &y, const size_t &z) const { size_t i; if (index(x, y, z, i)) { return valueAtIndex(i); } return NA(); } template< typename DataT> DataT CT_Grid3D::dataFromArray(const size_t &index) const { if (index >= nCells()) {return NA();} return _data[index]; } template< typename DataT> DataT CT_Grid3D::valueAtXYZ(const double x, const double y, const double z) const { size_t i; if (indexAtXYZ(x, y, z, i)) { return valueAtIndex(i); } return false; } template< typename DataT> bool CT_Grid3D::setMaxValueAtIndex(const size_t index, const DataT value) { if (index >= nCells()) {return false;} DataT currentValue = _data[index]; if ((currentValue == NA()) || (value > currentValue)) { return setValueAtIndex(index, value); } return false; } template< typename DataT> bool CT_Grid3D::setMaxValueAtXYZ(const double x, const double y, const double z, const DataT value) { size_t i; if (indexAtXYZ(x, y, z, i)) { return setMaxValueAtIndex(i, value); } return false; } template< typename DataT> bool CT_Grid3D::setMinValueAtIndex(const size_t index, DataT value) { if (index >= nCells()) {return false;} DataT currentValue = _data[index]; if ((currentValue == NA()) || (value < currentValue)) { return setValueAtIndex(index, value); } return false; } template< typename DataT> bool CT_Grid3D::setMinValueAtXYZ(const double x, const double y, const double z, const DataT value) { size_t i; if (indexAtXYZ(x, y, z, i)) { return setMinValueAtIndex(i, value); } return false; } template< typename DataT> bool CT_Grid3D::addValueAtIndex(const size_t index, DataT value) { if (index >= nCells()) {return false;} DataT currentValue = _data[index]; if (currentValue == NA()) { return setValueAtIndex(index, value); } else if (value != NA()) { return setValueAtIndex(index, value + currentValue); } return false; } template< typename DataT> bool CT_Grid3D::addValueAtXYZ(const double x, const double y, const double z, const DataT value) { size_t i; if (indexAtXYZ(x, y, z, i)) { return addValueAtIndex(i, value); } return false; } template< typename DataT> QList CT_Grid3D::neighboursValues(const size_t colx, const size_t liny, const size_t levz, const size_t distance, const bool keepNAs, const CenterMode centermode) const { QList liste; if (distance < 1) {return liste;} if (colx >= _dimx) {return liste;} if (liny >= _dimy) {return liste;} if (levz >= _dimz) {return liste;} size_t firstColx = colx-distance; size_t lastColx = colx+distance; size_t firstLiny = liny-distance; size_t lastLiny = liny+distance; size_t firstLinz = levz-distance; size_t lastLinz = levz+distance; if (firstColx >= _dimx) {firstColx = 0;} if (lastColx >= _dimx) {lastColx = _dimx - 1;} if (firstLiny >= _dimy) {firstLiny = 0;} if (lastLiny >= _dimy) {lastLiny = _dimy - 1;} if (firstLinz >= _dimz) {firstLinz = 0;} if (lastLinz >= _dimz) {lastLinz = _dimz - 1;} for (size_t xx = firstColx ; xx <= lastColx ; xx++) { for (size_t yy = firstLiny ; yy <= lastLiny ; yy++) { for (size_t zz = firstLinz ; zz <= lastLinz ; zz++) { DataT val = value(xx, yy, zz); if ((xx == colx) && (yy == liny) && (zz == levz)) { if (centermode == CM_KeepCenter) { if ((val != NA()) || keepNAs) {liste.append(val);} } else if (centermode == CM_NAasCenter) { liste.append(NA()); } } else { if ((val != NA()) || keepNAs) {liste.append(val);} } } } } return liste; } template< typename DataT> CT_AbstractItemDrawable* CT_Grid3D::copy(const CT_OutAbstractItemModel *model, const CT_AbstractResult *result, CT_ResultCopyModeList copyModeList) { Q_UNUSED(copyModeList); CT_Grid3D* cpy = new CT_Grid3D((const CT_OutAbstractSingularItemModel *)model, result, minX(), minY(), minZ(), _dimx, _dimy, _dimz, _res, _NAdata, _NAdata); cpy->setId(id()); for (size_t i = 0 ; i < nCells() ; i++) { cpy->setValueAtIndex(i, valueAtIndex(i)); } if (nCells() >0) { cpy->computeMinMax(); } cpy->setAlternativeDrawManager(getAlternativeDrawManager()); return cpy; } template< typename DataT> CT_AbstractItemDrawable* CT_Grid3D::copy(const QString &modelName, const CT_AbstractResult *result, CT_ResultCopyModeList copyModeList) { Q_UNUSED(copyModeList); CT_Grid3D* cpy = new CT_Grid3D(modelName, result, minX(), minY(), minZ(), _dimx, _dimy, _dimz, _res, _NAdata, _NAdata); cpy->setId(id()); for (size_t i = 0 ; i < nCells() ; i++) { cpy->setValueAtIndex(i, valueAtIndex(i)); } if (nCells() >0) { cpy->computeMinMax(); } cpy->setAlternativeDrawManager(getAlternativeDrawManager()); return cpy; } #endif // CT_GRID3D_HPP