#include "lvox3_stepextractcirculargrid.h" //In/Out #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" #include "ct_result/ct_resultgroup.h" //Tools #include "ct_view/ct_stepconfigurabledialog.h" #include "ct_view/tools/ct_configurablewidgettodialog.h" #include "tools/lvox3_errorcode.h" //Drawables #include "tools/lvox3_gridtype.h" //Models #define DEF_SearchInSourceResult "rs" #define DEF_SearchInSourceGroup "gs" #define DEF_SearchInGroup "grp" #define DEF_SearchInGrid "grid" LVOX3_StepExtractCircularGrid::LVOX3_StepExtractCircularGrid(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { _x = 0.00; _y = 0.00; _radiusmin = 0.00; _radius = 11.28; _zmin = -10000; _zmax = 10000; _isSquare = false; } QString LVOX3_StepExtractCircularGrid::getStepDescription() const { return tr("Extraction d'une grille circulaire"); } // Step detailed description QString LVOX3_StepExtractCircularGrid::getStepDetailledDescription() const { return tr("Cette étape permet d'extraire une grille 3D circulaire a partir d'une grille d'entrée, le but étant d'offrir un outil se rapprochant de la réalité forestière."); } CT_VirtualAbstractStep* LVOX3_StepExtractCircularGrid::createNewInstance(CT_StepInitializeData &dataInit) { // Creates an instance of this step return new LVOX3_StepExtractCircularGrid(dataInit); } void LVOX3_StepExtractCircularGrid::createInResultModelListProtected() { // We must have // - at least one grid CT_InResultModelGroupToCopy *inResultRefCopy = createNewInResultModelForCopy(DEF_SearchInSourceResult, tr("Grille d'entrée"), "", true); inResultRefCopy->setZeroOrMoreRootGroup(); inResultRefCopy->addGroupModel("", DEF_SearchInSourceGroup, CT_AbstractItemGroup::staticGetType(), tr("Groupe de référence"), "", CT_InAbstractGroupModel::CG_ChooseOneIfMultiple); inResultRefCopy->addItemModel(DEF_SearchInSourceGroup, DEF_SearchInGrid, LVOX3_AbstractGrid3D::staticGetType(), tr("Grille 3D")); } void LVOX3_StepExtractCircularGrid::createPostConfigurationDialog() { CT_StepConfigurableDialog *configDialog = newStandardPostConfigurationDialog(); configDialog->addDouble(tr("Coordonnée X du centre de la grille à extraire:"), "m", -1e+10, 1e+10, 4, _x); configDialog->addDouble(tr("Coordonnée Y du centre de la grille à extraire :"), "m", -1e+10, 1e+10, 4, _y); configDialog->addDouble(tr("Rayon de début de la grille à extraire :"), "m", 0, 1e+10, 4, _radiusmin); configDialog->addDouble(tr("Rayon de la grille à extraire (maximum) :"), "m", 0.01, 1e+10, 4, _radius); configDialog->addDouble(tr("Niveau Z minimum :"), "m", -1e+10, 1e+10, 4, _zmin); configDialog->addDouble(tr("Niveau Z maximum :"), "m", -1e+10, 1e+10, 4, _zmax); //configDialog->addBool (tr("Extract square grid :"), "m", false, _isSquare); } void LVOX3_StepExtractCircularGrid::createOutResultModelListProtected() { // create a new OUT result that is a copy of the IN result selected by the user CT_OutResultModelGroupToCopyPossibilities *resultModel = createNewOutResultModelToCopy(DEF_SearchInSourceResult); if (!resultModel) return; resultModel->addItemModel(DEF_SearchInSourceGroup, _grid_ModelName, new lvox::Grid3Df(), tr("Grille extraite")); } void LVOX3_StepExtractCircularGrid::compute() { CT_ResultGroup* outResult = getOutResultList().first(); CT_ResultGroupIterator itR(outResult, this, DEF_SearchInSourceGroup); //For every grid in the result while (itR.hasNext() && !isStopped()) { CT_StandardItemGroup *group = dynamic_cast((CT_AbstractItemGroup*)itR.next()); const LVOX3_AbstractGrid3D* inGrid = (const LVOX3_AbstractGrid3D*) group->firstItemByINModelName(this, DEF_SearchInGrid); size_t counterVoxels = 0; size_t n_voxels; //If grid has data if (inGrid != NULL) { //Number of voxels depending on grid resolution n_voxels = (inGrid->xdim()*inGrid->ydim()*inGrid->zdim()); qDebug()<< "inGrid not null"; //If grid has dimensions and voxel resolution if((inGrid->xdim() > 0) && (inGrid->ydim() > 0) && (inGrid->zdim() > 0) && (inGrid->xresolution() > 0) && (inGrid->yresolution() > 0) && (inGrid->zresolution() > 0)) { //Declaring output grid to be able to export personalized grid of profile lvox::Grid3Df *outGrid = new lvox::Grid3Df(_grid_ModelName.completeName(), outResult, inGrid->minX(), inGrid->minY(), inGrid->minZ(), inGrid->xdim(), inGrid->ydim(), inGrid->zdim(), inGrid->xresolution(),inGrid->yresolution(),inGrid->zresolution(), lvox::Max_Error_Code, 0); group->addItemDrawable(outGrid); //Iterates through the 3d ingrid for(size_t col = 0;col xdim() && (!isStopped());col++){ for(size_t lin = 0;lin ydim() && (!isStopped());lin++){ for(size_t level = 0;level zdim() && (!isStopped());level++){ Eigen::Vector3d centerCoordVoxel; size_t index; inGrid->index(col, lin, level, index); double value = inGrid->valueAtIndexAsDouble(index); inGrid->getCellCenterCoordinates(index,centerCoordVoxel); //Affects values in the outGrid if(evaluateVoxel(centerCoordVoxel, inGrid->xresolution(), inGrid->yresolution())){ outGrid->addValueAtIndex(index,value); }else{ //set to sky if voxel is outside of the outGrid //@TODO: may change to other value ? outGrid->addValueAtIndex(index, lvox::ErrorOrWarningCode::Sky); } ++counterVoxels; // progres de 0 à 100 setProgress((100.0*counterVoxels)/n_voxels); } } } outGrid->computeMinMax(); //computeMinMax at the end of the work on one grid to set visibility and colour coding } } } } //Test to see if any part of the voxel is inside the radius of the extracted grid (If it is, it is added to the extracted grid) bool LVOX3_StepExtractCircularGrid::evaluateVoxel(Eigen::Vector3d centerCoords, double gridResolutionX, double gridResolutionY){ //2D plane visualization of voxel square (topleft,topright,center,bottomleft,bottomright points) //If any of those points are in the distance, they are added to the grid. //The algorithm doesn't care if part of the voxel isn't in the zradius and another is, //because very big voxels will undoubtedly have a part that is outside double distance = sqrt(pow(_x-centerCoords(0),2.0)+pow(_y-centerCoords(1),2.0)); if(distance>= _radiusmin && distance <= _radius){ if(centerCoords(2)>=_zmin && centerCoords(2)<=_zmax) return true; } distance = sqrt(pow(_x-(centerCoords(0)-gridResolutionX),2.0)+pow(_y-(centerCoords(1)+gridResolutionY),2.0)); if(distance>= _radiusmin && distance <= _radius){ if(centerCoords(2)>=_zmin && centerCoords(2)<=_zmax) return true; } distance = sqrt(pow(_x-(centerCoords(0)+gridResolutionX),2.0)+pow(_y-(centerCoords(1)+gridResolutionY),2.0)); if(distance>= _radiusmin && distance <= _radius){ if(centerCoords(2)>=_zmin && centerCoords(2)<=_zmax) return true; } distance = sqrt(pow(_x-(centerCoords(0)-gridResolutionX),2.0)+pow(_y-(centerCoords(1)-gridResolutionY),2.0)); if(distance>= _radiusmin && distance <= _radius){ if(centerCoords(2)>=_zmin && centerCoords(2)<=_zmax) return true; } distance = sqrt(pow(_x-(centerCoords(0)+gridResolutionX),2.0)+pow(_y-(centerCoords(1)-gridResolutionY),2.0)); if(distance>= _radiusmin && distance <= _radius){ if(centerCoords(2)>=_zmin && centerCoords(2)<=_zmax) return true; } return false; }