#include "lvox3_stepextractcirculargrid.h" //Tools #include "tools/lvox3_errorcode.h" //Models #define DEF_SearchInSourceResult "rs" #define DEF_SearchInSourceGroup "gs" #define DEF_SearchInGroup "grp" #define DEF_SearchInGrid "grid" LVOX3_StepExtractCircularGrid::LVOX3_StepExtractCircularGrid() : CT_AbstractStep() { _x = 0.00; _y = 0.00; _radiusmin = 0.00; _radius = 11.28; _zmin = -10000; _zmax = 10000; _isSquare = false; } QString LVOX3_StepExtractCircularGrid::description() const { return tr("Circular grid extraction"); } // Step detailed description QString LVOX3_StepExtractCircularGrid::detailledDescription() const { return tr("This step allows for the extraction of a circular 3D grid from an input grid. This tool provides a mean to get closer to what is found in forestry."); } CT_VirtualAbstractStep* LVOX3_StepExtractCircularGrid::createNewInstance() const { // Creates an instance of this step return new LVOX3_StepExtractCircularGrid(); } QString LVOX3_StepExtractCircularGrid::outputDescription() const { auto indent = [](QString s) -> QString { return "
" + s+ "
"; }; return CT_AbstractStep::outputDescription() + "
Root group [Group]:" + indent("...") + indent("LVOX3_Grid3D [Extracted grid]"); } void LVOX3_StepExtractCircularGrid::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, "Input grid", "", true); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup, "Reference group"); manager.addItem(_inGroup, _inGrid, "3D grid"); } void LVOX3_StepExtractCircularGrid::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* configDialog) { configDialog->addDouble(tr("X coordinates of the new grid's center"), "m", -1e+10, 1e+10, 4, _x); configDialog->addDouble(tr("Y coordinates of the new grid's center"), "m", -1e+10, 1e+10, 4, _y); configDialog->addDouble(tr("Minimum radius of the new grid"), "m", 0, 1e+10, 4, _radiusmin); configDialog->addDouble(tr("Maximum radius of the new grid"), "m", 0.01, 1e+10, 4, _radius); configDialog->addDouble(tr("Minimum Z level"), "m", -1e+10, 1e+10, 4, _zmin); configDialog->addDouble(tr("Maximum Z level"), "m", -1e+10, 1e+10, 4, _zmax); //configDialog->addBool (tr("Extract square grid :"), "m", false, _isSquare); } void LVOX3_StepExtractCircularGrid::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outGrid, "Extracted grid"); } void LVOX3_StepExtractCircularGrid::compute() { for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { if (isStopped()) {return;} const LVOX3_AbstractGrid3D* inGrid = group->singularItem(_inGrid); 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(inGrid->minX(), inGrid->minY(), inGrid->minZ(), inGrid->xdim(), inGrid->ydim(), inGrid->zdim(), inGrid->xresolution(),inGrid->yresolution(),inGrid->zresolution(), lvox::Max_Error_Code, 0); group->addSingularItem(_outGrid, 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 = 0; 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; }