2044 lines
57 KiB
C++
2044 lines
57 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2020,
|
|
University in Hagen,
|
|
Faculty of Mathematics and Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO 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 General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
*/
|
|
|
|
|
|
#include "IrregularGrid3D.h"
|
|
#include "Algebras/Relation-C++/RelationAlgebra.h"
|
|
#include "Algebras/Collection/IntSet.h"
|
|
#include <map>
|
|
#include <iterator>
|
|
|
|
/*
|
|
Class Cell3D
|
|
|
|
*/
|
|
|
|
Cell3D::Cell3D() {
|
|
cellId = -1;
|
|
valFrom = -1;
|
|
valTo = -1;
|
|
nbrPoints = -1;
|
|
}
|
|
|
|
void
|
|
Cell3D::setCellId(int cell_id) {
|
|
this->cellId = cell_id;
|
|
}
|
|
|
|
int
|
|
Cell3D::getCellId() {
|
|
return cellId;
|
|
}
|
|
|
|
void
|
|
Cell3D::setValFrom(double val_from) {
|
|
valFrom = val_from;
|
|
}
|
|
|
|
double
|
|
Cell3D::getValFrom() {
|
|
return valFrom;
|
|
}
|
|
|
|
void
|
|
Cell3D::setValTo(double val_to) {
|
|
valTo = val_to;
|
|
}
|
|
|
|
double
|
|
Cell3D::getValTo() {
|
|
return valTo;
|
|
}
|
|
|
|
int
|
|
Cell3D::getNbrOfPoints() {
|
|
return nbrPoints;
|
|
}
|
|
|
|
void
|
|
Cell3D::setNbrOfPoints(int nbr_points) {
|
|
nbrPoints = nbr_points;
|
|
}
|
|
|
|
Cell3D::~Cell3D() { }
|
|
|
|
/*
|
|
Class VCell3D
|
|
|
|
*/
|
|
|
|
VCell3D::VCell3D() { }
|
|
|
|
std::vector<HCell3D>&
|
|
VCell3D::getRow() {
|
|
return row;
|
|
}
|
|
|
|
VCell3D::~VCell3D() { }
|
|
|
|
/*
|
|
Class SCell3D
|
|
|
|
*/
|
|
SCell::SCell() {
|
|
upper = nullptr;
|
|
neighbor = nullptr;
|
|
|
|
}
|
|
|
|
std::vector<SCell>&
|
|
HCell3D::getRect() {
|
|
return rect;
|
|
}
|
|
|
|
void
|
|
SCell::setUpper(SCell* upper_) {
|
|
upper = upper_;
|
|
}
|
|
|
|
SCell*
|
|
SCell::getUpper() {
|
|
return upper;
|
|
}
|
|
|
|
void
|
|
SCell::setNeighbor(SCell* neighbor_) {
|
|
neighbor = neighbor_;
|
|
}
|
|
|
|
SCell*
|
|
SCell::getNeighbor() {
|
|
return neighbor;
|
|
}
|
|
|
|
SCell::~SCell() { }
|
|
|
|
/*
|
|
Class HCell3D
|
|
|
|
*/
|
|
HCell3D::HCell3D() { }
|
|
HCell3D::~HCell3D() { }
|
|
|
|
|
|
/*
|
|
Class IrregularGrid3D
|
|
|
|
*/
|
|
IrregularGrid3D::IrregularGrid3D() {
|
|
boundingBox = nullptr;
|
|
rowCount = 0;
|
|
cellCount = 0;
|
|
layerCount = 0;
|
|
}
|
|
|
|
IrregularGrid3D::IrregularGrid3D(const IrregularGrid3D& g) {
|
|
boundingBox = g.boundingBox;
|
|
rowCount = g.rowCount;
|
|
cellCount = g.cellCount;
|
|
layerCount = g.layerCount;
|
|
}
|
|
|
|
IrregularGrid3D::IrregularGrid3D(Rectangle<3> &bounding_box,
|
|
int row_count, int cell_count, int layer_count) {
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
layerCount = layer_count;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::Set(Stream<Rectangle<3>> rStream,
|
|
Rectangle<3> &bounding_box,
|
|
int row_count, int cell_count, int layer_count) {
|
|
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
layerCount = layer_count;
|
|
|
|
createIrgrid3D(rStream);
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::SetVector(std::vector<Rectangle<3>>* rVector,
|
|
Rectangle<3> &bounding_box,
|
|
int row_count, int cell_count, int layer_count) {
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
layerCount = layer_count;
|
|
|
|
createIrgrid3DVector(rVector);
|
|
}
|
|
|
|
std::vector<CellInfo3D*>
|
|
IrregularGrid3D::getCellInfoVector(IrregularGrid3D *in_irgrid3d) {
|
|
std::vector<CellInfo3D*> cell_info_vect {};
|
|
|
|
/*
|
|
Divide space vertical => horizontal => spatial
|
|
SCells are final cells
|
|
|
|
*/
|
|
|
|
std::vector<VCell3D>* col = &in_irgrid3d->getColumnVector();
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell3D* vcell = &col->at(colIdx);
|
|
double vf = vcell->getValFrom();
|
|
double vt = vcell->getValTo();
|
|
|
|
std::vector<HCell3D>* row_vect = &vcell->getRow();
|
|
|
|
for(size_t cellIdx = 0; cellIdx < row_vect->size(); cellIdx++) {
|
|
HCell3D* cell = &row_vect->at(cellIdx);
|
|
int cid = cell->getCellId();
|
|
double hf = cell->getValFrom();
|
|
double ht = cell->getValTo();
|
|
|
|
std::vector<SCell>* rect_vect = &cell->getRect();
|
|
|
|
for(size_t rectIdx = 0; rectIdx < rect_vect->size(); rectIdx++) {
|
|
SCell* rect = &rect_vect->at(rectIdx);
|
|
int scid = rect->getCellId();
|
|
int nps = rect->getNbrOfPoints();
|
|
double sf = rect->getValFrom();
|
|
double st = rect->getValTo();
|
|
|
|
|
|
|
|
CellInfo3D* ci = new CellInfo3D(scid, cid, nps, hf, ht, vf, vt, sf, st);
|
|
cell_info_vect.push_back(ci);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return cell_info_vect;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::createIrgrid3D(Stream<Rectangle<3>> rStream) {
|
|
// sort input points by y-coordinates
|
|
processInput(rStream);
|
|
// create irregular grid 3d by point density
|
|
buildGrid();
|
|
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::createIrgrid3DVector(std::vector<Rectangle<3>>* rVector) {
|
|
// sort input points by y-coordinates
|
|
processInputVector(rVector);
|
|
// create irregular grid 3d by point density
|
|
buildGrid();
|
|
}
|
|
|
|
bool
|
|
pointComparisonX(CPoint p1, CPoint p2) {
|
|
return p1.x < p2.x;
|
|
}
|
|
|
|
bool
|
|
pointComparisonZ(CPoint p1, CPoint p2) {
|
|
return p1.z < p2.z;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::buildGrid() {
|
|
|
|
// create grid structure
|
|
double bb_top = boundingBox->getMaxY();
|
|
double bb_bot = boundingBox->getMinY();
|
|
double colOffset = (bb_top - bb_bot) / rowCount;
|
|
|
|
double bb_right = boundingBox->getMaxX();
|
|
double bb_left = boundingBox->getMinX();
|
|
double hOffset = (bb_right - bb_left) / cellCount;
|
|
|
|
double bb_bck = boundingBox->getMaxZ();
|
|
double bb_frnt = boundingBox->getMinZ();
|
|
double sOffset = (bb_bck - bb_frnt) / layerCount;
|
|
|
|
double col_boundary_val = bb_bot;
|
|
int hcell_id = 1;
|
|
int scell_id = 1;
|
|
|
|
|
|
// first divide space by rows
|
|
for(int c = 0; c < rowCount; c++) {
|
|
VCell3D vcell = VCell3D();
|
|
vcell.setValFrom(col_boundary_val);
|
|
|
|
col_boundary_val += colOffset;
|
|
vcell.setValTo(col_boundary_val);
|
|
|
|
double cell_boundary_val = bb_left;
|
|
// divide rows in cells
|
|
for(int r = 0; r < cellCount; r++) {
|
|
HCell3D hcell = HCell3D();
|
|
|
|
hcell.setValFrom(cell_boundary_val);
|
|
|
|
cell_boundary_val += hOffset;
|
|
hcell.setValTo(cell_boundary_val);
|
|
|
|
hcell.cellId = hcell_id;
|
|
hcell_id++;
|
|
// hcell.upper will be determined later
|
|
|
|
double rect_boundary_val = bb_frnt;
|
|
// divide cells in layers => result: final cells
|
|
for (int i = 0; i < layerCount; i++) {
|
|
SCell scell = SCell();
|
|
scell.setValFrom(rect_boundary_val);
|
|
|
|
rect_boundary_val += sOffset;
|
|
scell.setValTo(rect_boundary_val);
|
|
scell.cellId = scell_id;
|
|
scell_id++;
|
|
|
|
// will be determined later
|
|
scell.upper = nullptr;
|
|
scell.neighbor = nullptr;
|
|
|
|
hcell.getRect().push_back(scell);
|
|
}
|
|
|
|
|
|
cellVector.push_back(hcell);
|
|
vcell.getRow().push_back(hcell);
|
|
|
|
}
|
|
columnVector.push_back(vcell);
|
|
}
|
|
|
|
// adjust boundaries by point distribution
|
|
int nbrOfPoints = points.size();
|
|
int pointsPerRow = nbrOfPoints / rowCount;
|
|
std::vector<CPoint> tmp_row_points {};
|
|
std::vector<CPoint> tmp_row_points_hcell {};
|
|
std::vector<CPoint> tmp_row_points_scell {};
|
|
|
|
|
|
int pointIdx = 0;
|
|
int point_counter = 0;
|
|
for(int colIdx = 0; colIdx < rowCount; colIdx++) { //proof rows
|
|
for(size_t dp_idx = pointIdx; dp_idx < points.size(); dp_idx++) {
|
|
CPoint rp = points[dp_idx];
|
|
tmp_row_points.push_back(rp);
|
|
point_counter ++;
|
|
|
|
if ((point_counter == pointsPerRow) || (dp_idx == points.size()-1)) {
|
|
// adjust y-boundaries
|
|
if (colIdx > 0) {
|
|
|
|
getColumnVector()[colIdx].setValFrom(
|
|
getColumnVector()[colIdx-1].getValTo());
|
|
}
|
|
|
|
double new_val_to_y;
|
|
if (dp_idx == points.size()-1) {
|
|
new_val_to_y = bb_top;
|
|
} else {
|
|
new_val_to_y = rp.y;
|
|
|
|
}
|
|
|
|
getColumnVector()[colIdx].setValTo(new_val_to_y);
|
|
getColumnVector()[colIdx].setNbrOfPoints(point_counter);
|
|
|
|
point_counter = 0;
|
|
|
|
// adjust x-boundaries
|
|
std::sort(tmp_row_points.begin(), tmp_row_points.end(),
|
|
pointComparisonX);
|
|
|
|
int pointsPerCell = tmp_row_points.size() / cellCount;
|
|
|
|
int tmpPointIdx = 0;
|
|
for(int h = 0; h < cellCount; h++) {
|
|
std::vector<HCell3D>* hcel_vec_ptr = &columnVector[colIdx].getRow();
|
|
|
|
for(size_t tmp_rp_idx = tmpPointIdx;
|
|
tmp_rp_idx < tmp_row_points.size(); tmp_rp_idx++) {
|
|
|
|
CPoint rp_t = tmp_row_points[tmp_rp_idx];
|
|
tmp_row_points_hcell.push_back(rp_t);
|
|
point_counter ++;
|
|
|
|
if((point_counter == pointsPerCell)
|
|
|| (tmp_rp_idx == tmp_row_points.size()-1)
|
|
/* || (h == cellCount-1 ) */) {
|
|
|
|
double new_val_to_x;
|
|
if ((tmp_rp_idx == tmp_row_points.size())
|
|
|| (h == cellCount-1)) {
|
|
new_val_to_x = bb_right;
|
|
} else {
|
|
new_val_to_x = rp_t.x;
|
|
|
|
}
|
|
|
|
hcel_vec_ptr->at(h).setValTo(new_val_to_x);
|
|
getCellVector()[h].setValTo(new_val_to_x);
|
|
getCellVector()[h].setNbrOfPoints(point_counter);
|
|
|
|
if(h < cellCount-1) {
|
|
hcel_vec_ptr->at(h+1).setValFrom(new_val_to_x);
|
|
getCellVector()[h+1].setValFrom(new_val_to_x);
|
|
}
|
|
|
|
point_counter = 0;
|
|
|
|
//adjust z-boundaries
|
|
std::sort(tmp_row_points_hcell.begin(),
|
|
tmp_row_points_hcell.end(), pointComparisonZ);
|
|
|
|
int pointsPerRect = tmp_row_points_hcell.size() / layerCount;
|
|
int tmpPointIdz = 0;
|
|
for(int r = 0; r < layerCount; r++) {
|
|
std::vector<SCell>* scel_vec_ptr = &cellVector[h].getRect();
|
|
|
|
for(size_t tmp_rp_idz = tmpPointIdz;
|
|
tmp_rp_idz < tmp_row_points_hcell.size(); tmp_rp_idz++) {
|
|
|
|
CPoint rp_tt = tmp_row_points_hcell[tmp_rp_idz];
|
|
tmp_row_points_scell.push_back(rp_tt);
|
|
point_counter++;
|
|
|
|
if((point_counter == pointsPerRect)
|
|
|| (tmp_rp_idz == tmp_row_points_scell.size()-1)) {
|
|
|
|
if (r > 0) {
|
|
scel_vec_ptr->at(r).setValFrom(
|
|
scel_vec_ptr->at(r-1).getValTo());
|
|
|
|
}
|
|
|
|
double new_val_to_z;
|
|
if ((tmp_rp_idz == tmp_row_points_scell.size()-1)
|
|
|| (r == layerCount-1)) {
|
|
new_val_to_z = bb_bck;
|
|
} else {
|
|
new_val_to_z = rp_t.z;
|
|
}
|
|
scel_vec_ptr->at(r).setValTo(new_val_to_z);
|
|
|
|
tmpPointIdz = tmp_rp_idz + 1;
|
|
scel_vec_ptr->at(r).setNbrOfPoints(point_counter);
|
|
|
|
tmp_row_points_scell.clear();
|
|
// Smoothing in case of odd number of points per rect
|
|
if (r+1 < layerCount) {
|
|
pointsPerCell = (tmp_row_points_hcell.size()-tmpPointIdz)
|
|
/ (layerCount-1-r);
|
|
}
|
|
|
|
point_counter = 0;
|
|
// next rect
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
tmp_row_points_hcell.clear();
|
|
tmpPointIdx = tmp_rp_idx + 1;
|
|
hcel_vec_ptr->at(h).setNbrOfPoints(point_counter);
|
|
|
|
// Smoothing in case of odd number of points per cell
|
|
if (h+1 < cellCount) {
|
|
pointsPerCell = (tmp_row_points.size()-tmpPointIdx)
|
|
/ (cellCount-1-h);
|
|
}
|
|
point_counter = 0;
|
|
|
|
|
|
// next cell
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
tmp_row_points.clear();
|
|
pointIdx = dp_idx + 1;
|
|
|
|
// Smoothing in case of odd number of points per row
|
|
if (colIdx+1 < rowCount) {
|
|
pointsPerRow = (points.size()-pointIdx)
|
|
/ (rowCount-1-colIdx);
|
|
}
|
|
|
|
point_counter = 0;
|
|
|
|
// one row up
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// clear aux. vectors
|
|
/*if (points.size() > 0) {
|
|
points.clear();
|
|
}*/
|
|
|
|
if (tmp_row_points.size() > 0) {
|
|
tmp_row_points.clear();
|
|
}
|
|
if(tmp_row_points_hcell.size() > 0) {
|
|
tmp_row_points_hcell.clear();
|
|
}
|
|
if(tmp_row_points_scell.size() > 0) {
|
|
tmp_row_points_scell.clear();
|
|
}
|
|
|
|
std::vector<SCell>* row_lower = nullptr;
|
|
std::vector<SCell>* row_upper = nullptr;
|
|
std::vector<SCell>* row_neighbor = nullptr;
|
|
|
|
|
|
|
|
// update cell pointer
|
|
if(rowCount > 0 && cellCount > 0 && layerCount > 0)
|
|
{
|
|
for(int c = 0; c < rowCount; c++) {
|
|
for(int h = 0; h < cellCount; h++) {
|
|
|
|
int pointToCellIdx = 0;
|
|
int pointToCellIdz = 0;
|
|
|
|
|
|
// choose exact cell above current cell in z-layer
|
|
for(int s = 0; s < layerCount; s++) {
|
|
|
|
if(c < rowCount-1) {
|
|
|
|
row_lower = &getColumnVector().at(c).getRow().at(h).getRect();
|
|
row_upper = &getColumnVector().at(c+1).getRow().at(h).getRect();
|
|
SCell* lower_cell_ptr = &row_lower->at(s);
|
|
SCell* upper_cell_ptr = &row_upper->at(pointToCellIdx);
|
|
|
|
|
|
if(lower_cell_ptr->getValFrom() < upper_cell_ptr->getValTo()) {
|
|
lower_cell_ptr->setUpper(upper_cell_ptr);
|
|
|
|
} else {
|
|
SCell* next_upper_cell_ptr;
|
|
do {
|
|
pointToCellIdx ++;
|
|
next_upper_cell_ptr = &row_upper->at(pointToCellIdx);
|
|
lower_cell_ptr->setUpper(next_upper_cell_ptr);
|
|
|
|
} while (lower_cell_ptr->getValFrom()
|
|
>= next_upper_cell_ptr->getValTo());
|
|
}
|
|
|
|
}
|
|
|
|
/* Neighbor of lower_cell_ptr
|
|
compare z-values
|
|
|
|
*/
|
|
if(h < cellCount-1) {
|
|
row_lower = &getColumnVector().at(c).getRow().at(h).getRect();
|
|
row_neighbor = &getColumnVector().at(c).getRow().at(h+1).getRect();
|
|
SCell* lower_cell_ptr = &row_lower->at(s);
|
|
|
|
SCell* neighbor_cell_ptr = &row_neighbor->at(pointToCellIdz);
|
|
if(lower_cell_ptr->getValFrom() < neighbor_cell_ptr->getValTo()) {
|
|
lower_cell_ptr->setNeighbor(neighbor_cell_ptr);
|
|
|
|
} else {
|
|
SCell* next_neighbor_cell_ptr;
|
|
do {
|
|
pointToCellIdz++;
|
|
next_neighbor_cell_ptr = &row_neighbor->at(pointToCellIdz);
|
|
lower_cell_ptr->setNeighbor(next_neighbor_cell_ptr);
|
|
|
|
} while(lower_cell_ptr->getValFrom()
|
|
>= next_neighbor_cell_ptr->getValTo());
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const double min[] { boundingBox->getMinX(),
|
|
boundingBox->getMinY(), boundingBox->getMinZ() };
|
|
const double max[] { boundingBox->getMaxX(),
|
|
boundingBox->getMaxY(), boundingBox->getMaxZ() };
|
|
box.Set(true, min, max);
|
|
}
|
|
|
|
bool
|
|
pointComparisonY(CPoint p1, CPoint p2) {
|
|
return p1.y < p2.y;
|
|
}
|
|
|
|
/*
|
|
Returns centre of cuboid
|
|
|
|
*/
|
|
CPoint
|
|
getCuboidCentre(Rectangle<3>* r) {
|
|
double a = (r->getMaxY() - r->getMinY()) / (double)2;
|
|
double b = (r->getMaxX() - r->getMinX()) / (double)2;
|
|
double c = (r->getMaxZ() - r->getMinZ()) / (double)2;
|
|
|
|
CPoint r_c { (r->getMinX())+b, (r->getMinY())+a, (r->getMinZ()+c) };
|
|
|
|
return r_c;
|
|
}
|
|
|
|
/*
|
|
Check if a rectangle <3> is inside the irgrid3d bounding box
|
|
|
|
*/
|
|
bool
|
|
insideBoundingBox(Rectangle<3>* bbox, Rectangle<3>* r) {
|
|
double le = bbox->getMinX();
|
|
double ri = bbox->getMaxX();
|
|
double bo = bbox->getMinY();
|
|
double to = bbox->getMaxY();
|
|
double fr = bbox->getMinZ();
|
|
double bk = bbox->getMaxZ();
|
|
|
|
if (r->getMinX() >= le && r->getMaxX() <= ri
|
|
&& r->getMinY() >= bo && r->getMaxY() <=to
|
|
&& r->getMinZ() >= fr && r->getMaxZ() <= bk) {
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::processInput(Stream<Rectangle<3>> rStream) {
|
|
rStream.open();
|
|
Rectangle<3>* next = rStream.request();
|
|
|
|
while(next != 0){
|
|
if (!insideBoundingBox(boundingBox, next)) {
|
|
// rectangle (partially) outside the bounding box is discarded
|
|
next = rStream.request();
|
|
continue;
|
|
}
|
|
points.push_back(getCuboidCentre(next));
|
|
// free memory
|
|
delete next;
|
|
next = rStream.request();
|
|
}
|
|
rStream.close();
|
|
|
|
// sort point vector by y-coordinates
|
|
std::sort(points.begin(), points.end(), pointComparisonY);
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::processInputVector(std::vector<Rectangle<3>>* rVector) {
|
|
for (Rectangle<3> bbox : *rVector) {
|
|
if (!insideBoundingBox(boundingBox, &bbox)) {
|
|
// rectangle (partially) outside the bounding box is discarded
|
|
continue;
|
|
}
|
|
points.push_back(getCuboidCentre(&bbox));
|
|
}
|
|
|
|
// sort point vector by y-coordinates
|
|
std::sort(points.begin(), points.end(), pointComparisonY);
|
|
}
|
|
|
|
Rectangle<3> *
|
|
IrregularGrid3D::getBoundingBox() {
|
|
return boundingBox;
|
|
}
|
|
|
|
int
|
|
IrregularGrid3D::getRowCount() {
|
|
return rowCount;
|
|
}
|
|
|
|
int
|
|
IrregularGrid3D::getCellCount() {
|
|
return cellCount;
|
|
}
|
|
|
|
int
|
|
IrregularGrid3D::getLayerCount() {
|
|
return layerCount;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::setColumnVector(std::vector<VCell3D> column_vect) {
|
|
this->columnVector = column_vect;
|
|
}
|
|
|
|
void
|
|
IrregularGrid3D::setCellVector(std::vector<HCell3D> cell_vect) {
|
|
this->cellVector = cell_vect;
|
|
}
|
|
|
|
std::vector<VCell3D>&
|
|
IrregularGrid3D::getColumnVector() {
|
|
return this->columnVector;
|
|
}
|
|
|
|
std::vector<HCell3D>&
|
|
IrregularGrid3D::getCellVector() {
|
|
return this->cellVector;
|
|
}
|
|
|
|
IrregularGrid3D::~IrregularGrid3D() {}
|
|
|
|
ListExpr
|
|
IrregularGrid3D::PropertyIrGrid3D()
|
|
{
|
|
ListExpr desclst = nl->TextAtom();
|
|
nl->AppendText(desclst,
|
|
"A <rectangle<3>> bounding box followed by list of rows.\n"
|
|
"A row consists of two-element list (<from> <to>) "
|
|
"followed by list of cells.\n"
|
|
"A cell consists of a"
|
|
"three-element list\n(<from> <to> <id>) "
|
|
"followed by a list of layers.\n"
|
|
"A layer consists of a four-element list\n(<from> "
|
|
"<to> <id> <ref_id> <ref2_id>.");
|
|
|
|
ListExpr formatlst = nl->TextAtom();
|
|
nl->AppendText(formatlst,
|
|
"(0.0 2.0 0.0 2.0 0.0 2.0) ((0.0 0.3) ((0.0 0.25 1) "
|
|
"((0.0 1.0 1 5 3) (1.0 2.0 2 6 4)) "
|
|
" (0.25 2.0 2) ((0.0 1.0 3 7 -1) (1.0 2.0 4 8 -1)))"
|
|
"(0.3 2.0) ((0.0 0.375 3) ((0.0 1.0 5 -1 7) "
|
|
"(1.0 2.0 6 -1 8)) (0.375 2.0 4) "
|
|
" ((0.0 1.0 7 -1 -1) (1.0 2.0 8 -1 -1))))");
|
|
|
|
return (nl->TwoElemList(
|
|
nl->FourElemList(nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(nl->StringAtom("-> DATA"),
|
|
nl->StringAtom(IrregularGrid3D::BasicType()),
|
|
desclst,
|
|
formatlst)));
|
|
}
|
|
|
|
|
|
// Out function
|
|
ListExpr
|
|
IrregularGrid3D::OutIrGrid3D( ListExpr typeInfo, Word value ) {
|
|
IrregularGrid3D* irgrid3d = static_cast<IrregularGrid3D*>( value.addr );
|
|
if (irgrid3d != nullptr) {
|
|
|
|
Rectangle<3> * b_box = irgrid3d->getBoundingBox();
|
|
ListExpr bboxLstExpr = nl->SixElemList(
|
|
nl->RealAtom(b_box->getMinX()),
|
|
nl->RealAtom(b_box->getMaxX()),
|
|
nl->RealAtom(b_box->getMinY()),
|
|
nl->RealAtom(b_box->getMaxY()),
|
|
nl->RealAtom(b_box->getMinZ()),
|
|
nl->RealAtom(b_box->getMaxZ()));
|
|
|
|
std::vector<VCell3D>* col = &irgrid3d->getColumnVector();
|
|
ListExpr rowLstExpr = nl->Empty();
|
|
ListExpr lastRowLstExpr;
|
|
if (col->size() > 0) {
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell3D* vcell = &col->at(colIdx);
|
|
if (colIdx > 0) {
|
|
lastRowLstExpr = nl->Append(lastRowLstExpr,
|
|
nl->TwoElemList(nl->RealAtom(vcell->getValFrom()),
|
|
nl->RealAtom(vcell->getValTo())));
|
|
} else {
|
|
rowLstExpr = nl->OneElemList(
|
|
nl->TwoElemList(nl->RealAtom(vcell->getValFrom()),
|
|
nl->RealAtom(vcell->getValTo())));
|
|
lastRowLstExpr = rowLstExpr;
|
|
}
|
|
|
|
std::vector<HCell3D>* row_vect = &col->at(colIdx).getRow();
|
|
if (row_vect->size() > 0) {
|
|
ListExpr cellLstExpr;
|
|
ListExpr lastCellLstExpr;
|
|
for(size_t rowIdx = 0; rowIdx < row_vect->size(); rowIdx++) {
|
|
HCell3D* row_cell = &row_vect->at(rowIdx);
|
|
|
|
if (rowIdx > 0) {
|
|
lastCellLstExpr = nl->Append(lastCellLstExpr,
|
|
nl->ThreeElemList(nl->RealAtom(row_cell->getValFrom()),
|
|
nl->RealAtom(row_cell->getValTo()),
|
|
nl->IntAtom(row_cell->getCellId())));
|
|
} else {
|
|
cellLstExpr = nl->OneElemList(nl->ThreeElemList
|
|
(nl->RealAtom(row_cell->getValFrom()),
|
|
nl->RealAtom(row_cell->getValTo()),
|
|
nl->IntAtom(row_cell->getCellId())));
|
|
lastCellLstExpr = cellLstExpr;
|
|
}
|
|
|
|
std::vector<SCell>* cell_vect = &row_vect->at(rowIdx).getRect();
|
|
if(cell_vect->size() > 0) {
|
|
ListExpr layerLstExpr;
|
|
ListExpr lastLayerLstExpr;
|
|
for(size_t cellIdx = 0; cellIdx < cell_vect->size(); cellIdx++) {
|
|
SCell* cell_layer = &cell_vect->at(cellIdx);
|
|
|
|
if(cellIdx > 0) {
|
|
lastLayerLstExpr = nl->Append(lastLayerLstExpr,
|
|
nl->FiveElemList(nl->RealAtom(cell_layer->getValFrom()),
|
|
nl->RealAtom(cell_layer->getValTo()),
|
|
nl->IntAtom(cell_layer->getCellId()),
|
|
nl->IntAtom(cell_layer->getUpper() != nullptr
|
|
? cell_layer->getUpper()->getCellId() : -1),
|
|
nl->IntAtom(cell_layer->getNeighbor() != nullptr
|
|
? cell_layer->getNeighbor()->getCellId() : -1)
|
|
));
|
|
} else {
|
|
layerLstExpr = nl->OneElemList(nl->FiveElemList
|
|
(nl->RealAtom(cell_layer->getValFrom()),
|
|
nl->RealAtom(cell_layer->getValTo()),
|
|
nl->IntAtom(cell_layer->getCellId()),
|
|
nl->IntAtom(cell_layer->getUpper() != nullptr
|
|
? cell_layer->getUpper()->getCellId() : -1),
|
|
nl->IntAtom(cell_layer->getNeighbor() != nullptr
|
|
? cell_layer->getNeighbor()->getCellId() : -1)
|
|
));
|
|
lastLayerLstExpr = layerLstExpr;
|
|
}
|
|
}
|
|
lastCellLstExpr = nl->Append(lastCellLstExpr,layerLstExpr);
|
|
}
|
|
}
|
|
lastRowLstExpr = nl->Append(lastRowLstExpr, cellLstExpr);
|
|
}
|
|
}
|
|
}
|
|
ListExpr irgrid3dLstExpr = nl->TwoElemList(bboxLstExpr, rowLstExpr);
|
|
return irgrid3dLstExpr;
|
|
} else {
|
|
return nl->TheEmptyList();
|
|
|
|
//return (nl->SymbolAtom(Symbol::UNDEFINED()));
|
|
}
|
|
}
|
|
|
|
|
|
// In function
|
|
Word
|
|
IrregularGrid3D::InIrGrid3D( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct ) {
|
|
|
|
Word w = SetWord(Address(0));
|
|
try {
|
|
Rectangle<3>* bbox;
|
|
|
|
ListExpr bboxLstExpr;
|
|
ListExpr rowLstExpr;
|
|
|
|
if ( nl->ListLength( instance ) == 2 ) {
|
|
bboxLstExpr = nl->First(instance);
|
|
rowLstExpr = nl->Second(instance);
|
|
} else {
|
|
throw 1;
|
|
}
|
|
|
|
// fetch bounding box information from input
|
|
if (nl->ListLength( bboxLstExpr ) == 6 ) {
|
|
ListExpr left = nl->First(bboxLstExpr);
|
|
ListExpr right = nl->Second(bboxLstExpr);
|
|
ListExpr bottom = nl->Third(bboxLstExpr);
|
|
ListExpr top = nl->Fourth(bboxLstExpr);
|
|
ListExpr front = nl->Fifth(bboxLstExpr);
|
|
ListExpr back = nl->Sixth(bboxLstExpr);
|
|
|
|
if ( nl->IsAtom(left) && nl->AtomType(left) == RealType
|
|
&& nl->IsAtom(right) && nl->AtomType(right) == RealType
|
|
&& nl->IsAtom(bottom) && nl->AtomType(bottom) == RealType
|
|
&& nl->IsAtom(top) && nl->AtomType(top) == RealType
|
|
&& nl->IsAtom(front) && nl->AtomType(front) == RealType
|
|
&& nl->IsAtom(back) && nl->AtomType(back) == RealType) {
|
|
|
|
double min[3], max[3];
|
|
min[0] = nl->RealValue(left);
|
|
min[1] = nl->RealValue(bottom);
|
|
max[0] = nl->RealValue(right);
|
|
max[1] = nl->RealValue(top);
|
|
min[2] = nl->RealValue(front);
|
|
max[2] = nl->RealValue(back);
|
|
|
|
bbox = new Rectangle<3>(true, min, max);
|
|
} else {
|
|
throw 3;
|
|
}
|
|
|
|
} else {
|
|
throw 2;
|
|
}
|
|
|
|
// fetch row information from input
|
|
|
|
// temporary support structures
|
|
std::map<int, int> cellRef;
|
|
std::map<int, int> NeighbRef;
|
|
std::map<int, SCell*> cellIds;
|
|
|
|
std::vector<VCell3D> column_vec {};
|
|
std::vector<HCell3D> cell_vec {};
|
|
int row_cnt = 0;
|
|
int cell_cnt = 0;
|
|
int layer_cnt = 0;
|
|
if (nl->ListLength( rowLstExpr ) > 1 ) {
|
|
VCell3D vc;
|
|
HCell3D hc;
|
|
VCell3D* vc_ptr;
|
|
HCell3D* hc_ptr;
|
|
|
|
while(!nl->IsEmpty(rowLstExpr)) {
|
|
ListExpr lstElem = nl->First(rowLstExpr);
|
|
|
|
if ((nl->ListLength(lstElem)) == 2
|
|
&& (nl->IsAtom(nl->First(lstElem))
|
|
&& nl->IsAtom(nl->Second(lstElem))) ) {
|
|
// a two-element double list initiates a new row
|
|
row_cnt ++;
|
|
ListExpr fLst = nl->First(lstElem);
|
|
ListExpr tLst = nl->Second(lstElem);
|
|
|
|
if ( nl->AtomType(fLst) == RealType
|
|
&& nl->AtomType(tLst) == RealType) {
|
|
vc = VCell3D();
|
|
|
|
vc.setValFrom(nl->RealValue(fLst));
|
|
vc.setValTo(nl->RealValue(tLst));
|
|
column_vec.push_back(vc);
|
|
vc_ptr = &(column_vec.back());
|
|
}
|
|
} else {
|
|
ListExpr rowLstExpr = lstElem;
|
|
|
|
while(!nl->IsEmpty(rowLstExpr)) {
|
|
// cell information
|
|
ListExpr cellLstExpr = nl->First(rowLstExpr);
|
|
if (nl->ListLength( cellLstExpr ) == 3) {
|
|
// a three-element list initiates a new rectangle
|
|
ListExpr cv1Lst = nl->First(cellLstExpr);
|
|
ListExpr cv2Lst = nl->Second(cellLstExpr);
|
|
ListExpr cv3Lst = nl->Third(cellLstExpr);
|
|
|
|
if ( nl->IsAtom(cv1Lst) && nl->AtomType(cv1Lst) == RealType
|
|
&& nl->IsAtom(cv2Lst) && nl->AtomType(cv2Lst) == RealType
|
|
&& nl->IsAtom(cv3Lst) && nl->AtomType(cv3Lst) == IntType
|
|
) {
|
|
hc = HCell3D();
|
|
hc.setValFrom(nl->RealValue(cv1Lst));
|
|
hc.setValTo(nl->RealValue(cv2Lst));
|
|
hc.setCellId(nl->IntValue(cv3Lst));
|
|
// will be determined later
|
|
//hc->setUpper(nullptr);
|
|
|
|
vc_ptr->getRow().push_back(hc);
|
|
cell_vec.push_back(hc);
|
|
hc_ptr = &(vc_ptr->getRow().back());
|
|
//hc_ptr = &(cell_vec.back());
|
|
} else {
|
|
throw 5;
|
|
}
|
|
} else {
|
|
//ListExpr rowLstExpr = cellLstExpr;
|
|
while(!nl->IsEmpty(cellLstExpr)) {
|
|
ListExpr layerLstExpr = nl->First(cellLstExpr);
|
|
if(nl->ListLength( layerLstExpr ) == 5) {
|
|
// a five-element list initiates a new layer/ the whole cell
|
|
ListExpr lv1Lst = nl->First(layerLstExpr);
|
|
ListExpr lv2Lst = nl->Second(layerLstExpr);
|
|
ListExpr lv3Lst = nl->Third(layerLstExpr);
|
|
ListExpr lv4Lst = nl->Fourth(layerLstExpr);
|
|
ListExpr lv5Lst = nl->Fifth(layerLstExpr);
|
|
|
|
if(nl->IsAtom(lv1Lst) && nl->AtomType(lv1Lst) == RealType
|
|
&& nl->IsAtom(lv2Lst) && nl->AtomType(lv2Lst) == RealType
|
|
&& nl->IsAtom(lv3Lst) && nl->AtomType(lv3Lst) == IntType
|
|
&& nl->IsAtom(lv4Lst) && nl->AtomType(lv4Lst) == IntType
|
|
&& nl->IsAtom(lv5Lst) && nl->AtomType(lv5Lst) == IntType) {
|
|
SCell* sc = new SCell();
|
|
sc->setValFrom(nl->RealValue(lv1Lst));
|
|
sc->setValTo(nl->RealValue(lv2Lst));
|
|
sc->setCellId(nl->IntValue(lv3Lst));
|
|
sc->setUpper(nullptr);
|
|
sc->setNeighbor(nullptr);
|
|
hc_ptr->getRect().push_back(*sc);
|
|
|
|
int cellRefId = nl->IntValue(lv4Lst);
|
|
if (cellRefId != -1) {
|
|
cellRef.insert(std::make_pair(
|
|
((int)nl->IntValue(lv3Lst)), cellRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
((int)nl->IntValue(lv3Lst)), sc));
|
|
|
|
int NeighbRefId = nl->IntValue(lv5Lst);
|
|
if(NeighbRefId != -1) {
|
|
NeighbRef.insert(std::make_pair(
|
|
((int)nl->IntValue(lv3Lst)), NeighbRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
((int)nl->IntValue(lv3Lst)), sc));
|
|
}
|
|
}
|
|
cellLstExpr = nl->Rest(cellLstExpr);
|
|
}
|
|
}
|
|
if(cell_cnt > 0 && layer_cnt == 0) {
|
|
layer_cnt = hc_ptr->getRect().size();
|
|
}
|
|
rowLstExpr = nl->Rest(rowLstExpr);
|
|
}
|
|
}
|
|
// determine number of cells (one-time)
|
|
if (row_cnt > 0 && cell_cnt == 0) {
|
|
cell_cnt = vc_ptr->getRow().size();
|
|
|
|
}
|
|
rowLstExpr = nl->Rest(rowLstExpr);
|
|
}
|
|
|
|
} else {
|
|
throw 4;
|
|
}
|
|
|
|
// update pointer
|
|
if (row_cnt > 0 && cell_cnt > 0 && layer_cnt > 0) {
|
|
for(int colIdx = 0; colIdx < row_cnt; colIdx++) {
|
|
VCell3D* vcell = &column_vec.at(colIdx);
|
|
std::vector<HCell3D>* row_vect = &vcell->getRow();
|
|
for(int cIdx = 0; cIdx < cell_cnt; cIdx++) {
|
|
HCell3D* hcell = &(*row_vect).at(cIdx);
|
|
std::vector<SCell>* cell_vect = &hcell->getRect();
|
|
|
|
for(int lIdx = 0; lIdx < layer_cnt; lIdx++) {
|
|
SCell* scell = &(*cell_vect).at(lIdx);
|
|
if(cellRef.find(scell->getCellId()) != cellRef.end()) {
|
|
int cell_ref = cellRef.at(scell->getCellId());
|
|
if(cellIds.find(cell_ref) != cellIds.end()) {
|
|
scell->setUpper(cellIds.at(cell_ref));
|
|
}
|
|
}
|
|
if(NeighbRef.find(scell->getCellId()) != NeighbRef.end()) {
|
|
int neighb_ref = NeighbRef.at(scell->getCellId());
|
|
if(cellIds.find(neighb_ref) != cellIds.end()) {
|
|
scell->setNeighbor(cellIds.at(neighb_ref));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
correct = true;
|
|
IrregularGrid3D* irgrid = new IrregularGrid3D(*bbox,
|
|
row_cnt, cell_cnt, layer_cnt);
|
|
irgrid->setColumnVector(column_vec);
|
|
irgrid->setCellVector(cell_vec);
|
|
irgrid->box = *bbox;
|
|
w.addr = irgrid;
|
|
return w;
|
|
} catch (int e) {
|
|
correct = false;
|
|
cmsg.inFunError("Expecting a irgrid3d list representation. Exit code "
|
|
+ std::to_string(e));
|
|
|
|
return w;
|
|
}
|
|
}
|
|
|
|
// This function checks whether the type constructor is applied correctly.
|
|
bool
|
|
IrregularGrid3D::KindCheckIrGrid3D( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, IrregularGrid3D::BasicType() ));
|
|
}
|
|
|
|
// Close -function
|
|
void
|
|
IrregularGrid3D::CloseIrGrid3D( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete (IrregularGrid3D *)w.addr;
|
|
w.addr = 0;
|
|
}
|
|
|
|
// Clone function
|
|
Word
|
|
IrregularGrid3D::CloneIrGrid3D( const ListExpr typeInfo, const Word& w )
|
|
{
|
|
IrregularGrid3D *g = new IrregularGrid3D( *((IrregularGrid3D *)w.addr) );
|
|
return SetWord( g );
|
|
}
|
|
|
|
// Create function
|
|
Word
|
|
IrregularGrid3D::CreateIrGrid3D( const ListExpr typeInfo )
|
|
{
|
|
return SetWord( new IrregularGrid3D() );
|
|
}
|
|
|
|
// Delete function
|
|
void
|
|
IrregularGrid3D::DeleteIrGrid3D( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete (IrregularGrid3D *)w.addr;
|
|
w.addr = 0;
|
|
}
|
|
|
|
// SizeOf function
|
|
int
|
|
IrregularGrid3D::SizeOfIrGrid3D()
|
|
{
|
|
return sizeof(IrregularGrid3D);
|
|
}
|
|
|
|
bool IrregularGrid3D::OpenIrGrid3D( SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value){
|
|
|
|
size_t size = sizeof(int);
|
|
size_t sizeD = sizeof(double);
|
|
int xr = 0, yb = 0, yt = 0;
|
|
size_t cols = 0, rows = 0, cellsize = 0;
|
|
std::vector<VCell3D> column_vec {};
|
|
std::vector<HCell3D> cell_vec {};
|
|
VCell3D vc;
|
|
HCell3D hc;
|
|
VCell3D* vc_ptr;
|
|
HCell3D* hc_ptr;
|
|
std::map<int, int> cellRef;
|
|
std::map<int, int> NeighbRef;
|
|
std::map<int, SCell> cellIds;
|
|
|
|
double vf = 0.0, vt = 0.0; //column values
|
|
double rvf = 0.0, rvt = 0.0; // row values
|
|
double cvf = 0.0, cvt = 0.0; // cell values
|
|
int rid = 0, cellid = 0, cellu = 0, celln = 0;
|
|
double xmin=0.0, xmax=0.0, ymin=0.0, ymax=0.0, zmin=0.0, zmax=0.0;
|
|
bool ok = true;
|
|
|
|
ok = ok && valueRecord.Read( &xmin, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &xmax, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &ymin, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &ymax, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &zmin, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &zmax, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
ok = ok && valueRecord.Read( &xr, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &yb, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &yt, size, offset );
|
|
offset += size;
|
|
|
|
// colsize
|
|
ok = ok && valueRecord.Read( &cols, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t i = 0; i < cols; i++)
|
|
{
|
|
vc = VCell3D();
|
|
ok = ok && valueRecord.Read( &vf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &vt, sizeD, offset );
|
|
offset += sizeD;
|
|
vc.setValFrom(vf);
|
|
vc.setValTo(vt);
|
|
column_vec.push_back(vc);
|
|
vc_ptr = &(column_vec.back());
|
|
|
|
//rowsize
|
|
ok = ok && valueRecord.Read( &rows, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t j = 0; j < rows; j++)
|
|
{
|
|
hc = HCell3D();
|
|
ok = ok && valueRecord.Read( &rvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &rvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &rid, size, offset );
|
|
offset += size;
|
|
hc.setValFrom(rvf);
|
|
hc.setValTo(rvt);
|
|
hc.setCellId(rid);
|
|
vc_ptr->getRow().push_back(hc);
|
|
cell_vec.push_back(hc);
|
|
hc_ptr = &(vc_ptr->getRow().back());
|
|
|
|
ok = ok && valueRecord.Read( &cellsize, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t k = 0; k < cellsize; k++)
|
|
{
|
|
ok = ok && valueRecord.Read( &cvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &cvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &cellid, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &cellu, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &celln, size, offset );
|
|
offset += size;
|
|
|
|
SCell sc = SCell();
|
|
sc.setValFrom(cvf);
|
|
sc.setValTo(cvt);
|
|
sc.setCellId(cellid);
|
|
sc.setUpper(nullptr);
|
|
sc.setNeighbor(nullptr);
|
|
hc_ptr->getRect().push_back(sc);
|
|
|
|
int cellRefId = cellu;
|
|
if (cellRefId != -1) {
|
|
cellRef.insert(std::make_pair(
|
|
cellid, cellRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
cellid, sc));
|
|
|
|
int NeighbRefId = celln;
|
|
if(NeighbRefId != -1) {
|
|
NeighbRef.insert(std::make_pair(
|
|
cellid, NeighbRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
cellid, sc));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// update pointer
|
|
if (xr > 0 && yb > 0 && yt > 0) {
|
|
for(int colIdx = 0; colIdx < xr; colIdx++) {
|
|
VCell3D* vcell = &column_vec.at(colIdx);
|
|
std::vector<HCell3D>* row_vect = &vcell->getRow();
|
|
for(int cIdx = 0; cIdx < yb; cIdx++) {
|
|
HCell3D* hcell = &(*row_vect).at(cIdx);
|
|
std::vector<SCell>* cell_vect = &hcell->getRect();
|
|
|
|
for(int lIdx = 0; lIdx < yt; lIdx++) {
|
|
SCell* scell = &(*cell_vect).at(lIdx);
|
|
if(cellRef.find(scell->getCellId()) != cellRef.end()) {
|
|
int cell_ref = cellRef.at(scell->getCellId());
|
|
if(cellIds.find(cell_ref) != cellIds.end()) {
|
|
scell->setUpper(&cellIds.at(cell_ref));
|
|
}
|
|
}
|
|
if(NeighbRef.find(scell->getCellId()) != NeighbRef.end()) {
|
|
int neighb_ref = NeighbRef.at(scell->getCellId());
|
|
if(cellIds.find(neighb_ref) != cellIds.end()) {
|
|
scell->setNeighbor(&cellIds.at(neighb_ref));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const double min[] { xmin, ymin, zmin };
|
|
const double max[] { xmax, ymax, zmax };
|
|
Rectangle<3> *bbox = new Rectangle<3>(true, min, max);
|
|
IrregularGrid3D* irgrid = new IrregularGrid3D(*bbox,
|
|
xr, yb, yt);
|
|
irgrid->setColumnVector(column_vec);
|
|
irgrid->setCellVector(cell_vec);
|
|
irgrid->box = *bbox;
|
|
value.addr = irgrid;
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
bool IrregularGrid3D::SaveIrGrid3D(SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value) {
|
|
|
|
|
|
IrregularGrid3D* r = static_cast<IrregularGrid3D*>( value.addr );
|
|
|
|
size_t size = sizeof(int);
|
|
size_t sizeD = sizeof(double);
|
|
bool ok = true;
|
|
|
|
double minx = r->box.getMinX();
|
|
double maxx = r->box.getMaxX();
|
|
double miny = r->box.getMinY();
|
|
double maxy = r->box.getMaxY();
|
|
double minz = r->box.getMinZ();
|
|
double maxz = r->box.getMaxZ();
|
|
|
|
ok = ok && valueRecord.Write(&minx, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&maxx, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&miny, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&maxy, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&minz, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&maxz, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
ok = ok && valueRecord.Write(&r->rowCount, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&r->cellCount, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&r->layerCount, size, offset );
|
|
offset += size;
|
|
|
|
std::vector<VCell3D>* col = &r->getColumnVector();
|
|
size_t cols = col->size();
|
|
if (col->size() > 0) {
|
|
ok = ok && valueRecord.Write(&cols, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell3D* vcell = &col->at(colIdx);
|
|
double vf = vcell->getValFrom();
|
|
double vt = vcell->getValTo();
|
|
ok = ok && valueRecord.Write(&vf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&vt, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
std::vector<HCell3D>* row_vect = &col->at(colIdx).getRow();
|
|
size_t rows = row_vect->size();
|
|
if (row_vect->size() > 0) {
|
|
ok = ok && valueRecord.Write(&rows, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t rowIdx = 0; rowIdx < row_vect->size(); rowIdx++) {
|
|
HCell3D* row_cell = &row_vect->at(rowIdx);
|
|
double rvf = row_cell->getValFrom();
|
|
double rvt = row_cell->getValTo();
|
|
int ri = row_cell->getCellId();
|
|
ok = ok && valueRecord.Write(&rvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&rvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&ri, size, offset );
|
|
offset += size;
|
|
|
|
std::vector<SCell>* cell_vect = &row_vect->at(rowIdx).getRect();
|
|
size_t cellsize = cell_vect->size();
|
|
if(cell_vect->size() > 0) {
|
|
ok = ok && valueRecord.Write(&cellsize, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t cellIdx = 0; cellIdx < cell_vect->size(); cellIdx++) {
|
|
SCell* cell_layer = &cell_vect->at(cellIdx);
|
|
double cvf = cell_layer->getValFrom();
|
|
double cvt = cell_layer->getValTo();
|
|
int ci = cell_layer->getCellId();
|
|
int cu = cell_layer->getUpper() != nullptr
|
|
? cell_layer->getUpper()->getCellId() : -1;
|
|
int cn = cell_layer->getNeighbor() != nullptr
|
|
? cell_layer->getNeighbor()->getCellId() : -1;
|
|
|
|
ok = ok && valueRecord.Write(&cvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&cvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&ci, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&cu, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&cn, size, offset );
|
|
offset += size;
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
Type mapping function ~IrGrid3dFeedTypeMap~
|
|
|
|
It is used for the ~feed~ operator.
|
|
|
|
*/
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid3dFeedTypeMap( ListExpr args )
|
|
{
|
|
|
|
if(nl->HasLength(args, 1)) {
|
|
|
|
ListExpr first = nl->First(args);
|
|
if (IrregularGrid3D::checkType(first)) {
|
|
ListExpr resAttrList = nl->ThreeElemList(
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Id"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Count"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Cell3D"),
|
|
nl->SymbolAtom(Rectangle<3>::BasicType())));
|
|
|
|
return nl->TwoElemList(listutils::basicSymbol<Stream<Tuple>>(),
|
|
nl->TwoElemList(
|
|
listutils::basicSymbol<Tuple>(),
|
|
resAttrList));
|
|
|
|
}
|
|
}
|
|
const std::string errMsg = "The following argument is expected:"
|
|
" irgrid3d";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
// for value mapping function of ~feed~ operator
|
|
struct IrGrid3DTupleInfo
|
|
{
|
|
std::vector<CellInfo3D*> cell_info_vect;
|
|
unsigned int currentTupleIdx;
|
|
ListExpr numTupleTypeList;
|
|
|
|
void init(IrregularGrid3D *irgrid3d_in) {
|
|
currentTupleIdx = 0;
|
|
cell_info_vect = IrregularGrid3D::getCellInfoVector(irgrid3d_in);
|
|
|
|
ListExpr tupleTypeLst = nl->TwoElemList(
|
|
nl->SymbolAtom(Tuple::BasicType()),
|
|
nl->ThreeElemList(
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Id"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Count"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Cell3D"),
|
|
nl->SymbolAtom(Rectangle<3>::BasicType()))));
|
|
|
|
SecondoCatalog* sc = SecondoSystem::GetCatalog();
|
|
numTupleTypeList = sc->NumericType(tupleTypeLst);
|
|
}
|
|
|
|
TupleType* getTupleType() {
|
|
TupleType *tupleType = new TupleType(numTupleTypeList);
|
|
|
|
return tupleType;
|
|
}
|
|
|
|
Tuple* getNext(TupleType *ttype) {
|
|
if (currentTupleIdx < cell_info_vect.size()) {
|
|
|
|
CellInfo3D * cell_info = cell_info_vect.at(currentTupleIdx);
|
|
int tp_p1 = cell_info->cellId;
|
|
int tp_p2 = cell_info->statNbrOfPoints;
|
|
Rectangle<3> tp_p3 = *cell_info->cell;
|
|
|
|
Tuple *tuple = new Tuple(ttype);
|
|
tuple->PutAttribute(0, new CcInt(true, tp_p1));
|
|
tuple->PutAttribute(1, new CcInt(true, tp_p2));
|
|
tuple->PutAttribute(2, new Rectangle<3> (tp_p3));
|
|
|
|
currentTupleIdx++;
|
|
return tuple;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
Value mapping function of operator ~feed~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid3dValueMapFeed( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
IrregularGrid3D *input_irgrid3d_ptr =
|
|
static_cast<IrregularGrid3D*>( args[0].addr );
|
|
IrGrid3DTupleInfo* tp_info = static_cast<IrGrid3DTupleInfo*>(local.addr);
|
|
TupleType* tupleType = nullptr;
|
|
Tuple* tuple = nullptr;
|
|
|
|
switch (message) {
|
|
case OPEN: {
|
|
tp_info = new IrGrid3DTupleInfo();
|
|
tp_info->init(input_irgrid3d_ptr);
|
|
local.addr = tp_info;
|
|
return 0;
|
|
}
|
|
case REQUEST: {
|
|
if (local.addr) {
|
|
tp_info = ((IrGrid3DTupleInfo*)local.addr);
|
|
tupleType = tp_info->getTupleType();
|
|
} else {
|
|
return CANCEL;
|
|
}
|
|
// get next tuple
|
|
tuple = tp_info->getNext(tupleType);
|
|
|
|
if (tuple != nullptr) {
|
|
result.addr = tuple;
|
|
return YIELD;
|
|
} else {
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
}
|
|
case CLOSE: {
|
|
if (local.addr) {
|
|
|
|
tp_info = ((IrGrid3DTupleInfo*)local.addr);
|
|
delete tp_info;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
Type mapping function ~IrGrid3dCellnosTypeMap~
|
|
|
|
It is used for the ~cellnos\_ir~ operator.
|
|
|
|
*/
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid3dCellnosTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 2)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
|
|
if (IrregularGrid3D::checkType(first) && Rectangle<3>::checkType(second)) {
|
|
return nl->SymbolAtom(collection::IntSet::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following two arguments are expected:"
|
|
" irgrid3d x rect<3>";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid3dSCCTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 4)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
ListExpr third = nl->Third(args);
|
|
ListExpr fourth = nl->Fourth(args);
|
|
|
|
if (IrregularGrid3D::checkType(first) && Rectangle<3>::checkType(second)
|
|
&& Rectangle<3>::checkType(third) && CcInt::checkType(fourth)) {
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following four arguments are expected:"
|
|
" irgrid3d x rect3d x rect3 x int";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid3dGetCellTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 2)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
|
|
if (IrregularGrid3D::checkType(first) && CcInt::checkType(second)) {
|
|
return nl->SymbolAtom(Rectangle<3>::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following two arguments are expected:"
|
|
" irgrid3d x int";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid3dBBoxTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 1)) {
|
|
ListExpr first = nl->First(args);
|
|
|
|
if (Stream<Rectangle<3>>::checkType(first)) {
|
|
return nl->SymbolAtom(Rectangle<3>::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following argument is expected:"
|
|
" stream<rect<3>>";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid3D::IrGrid2dBBoxTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 1)) {
|
|
ListExpr first = nl->First(args);
|
|
|
|
if (Stream<Rectangle<2>>::checkType(first)) {
|
|
return nl->SymbolAtom(Rectangle<2>::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following argument is expected:"
|
|
" stream<rect>";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
template <class C>
|
|
bool
|
|
InCell(C cell, double val) {
|
|
return (val >= cell.getValFrom()
|
|
&& val < cell.getValTo());
|
|
}
|
|
|
|
template <class C>
|
|
bool
|
|
GtCell(C cell, double val) {
|
|
return (cell.getValFrom() >= val);
|
|
}
|
|
|
|
template <class C>
|
|
int
|
|
CellBS(const std::vector<C>* c_vec, int start, int end, const double val) {
|
|
if (start > end) {
|
|
return -1;
|
|
}
|
|
const int mid = start + ((end - start) / 2);
|
|
if (InCell(c_vec->at(mid), val)) {
|
|
return mid;
|
|
} else if (GtCell(c_vec->at(mid), val)) {
|
|
return CellBS(c_vec, start, mid-1, val);
|
|
}
|
|
|
|
return CellBS(c_vec, mid+1, end, val);
|
|
}
|
|
|
|
/*
|
|
returns cellnumbers of cells which a given
|
|
cuboid intersects
|
|
|
|
*/
|
|
void
|
|
cellNum(IrregularGrid3D *input_irgrid3d_ptr,
|
|
Rectangle<3> *search_window_ptr, std::set<int> *cell_ids){
|
|
std::vector<VCell3D>* col = &input_irgrid3d_ptr->getColumnVector();
|
|
|
|
double le = search_window_ptr->getMinX();
|
|
double ri = search_window_ptr->getMaxX();
|
|
double bo = search_window_ptr->getMinY();
|
|
double to = search_window_ptr->getMaxY();
|
|
double fr = search_window_ptr->getMinZ();
|
|
double ba = search_window_ptr->getMaxZ();
|
|
|
|
// check for 3d
|
|
if(le == ri || bo == to || fr == ba)
|
|
{
|
|
//cell_ids->insert(0);
|
|
return;
|
|
}
|
|
|
|
int pos_bo = CellBS(col, 0, col->size(), bo);
|
|
if (pos_bo != -1) {
|
|
VCell3D vCell = col->at(pos_bo);
|
|
std::vector<HCell3D>* row = &vCell.getRow();
|
|
|
|
int pos_le = CellBS(row, 0, row->size(), le);
|
|
if (pos_le != -1) {
|
|
HCell3D hcell = row->at(pos_le);
|
|
std::vector<SCell>* cells = &hcell.getRect();
|
|
|
|
int pos_fr = CellBS(cells, 0, cells->size(), fr);
|
|
if(pos_fr != -1) {
|
|
|
|
// collect ids
|
|
unsigned int cellIdx = pos_fr;
|
|
int pos_left = pos_le;
|
|
SCell begin_i = cells->at(cellIdx); // first cell
|
|
while (cellIdx < cells->size()) {
|
|
SCell i = cells->at(cellIdx);
|
|
cell_ids->insert(i.getCellId());
|
|
|
|
|
|
if((ba >= i.getValFrom() && ba <= i.getValTo())
|
|
|| (cellIdx == cells->size()-1 && ba >= i.getValFrom())) {
|
|
SCell fi = cells->at(pos_fr);
|
|
|
|
if(ri > hcell.getValTo() && fi.getNeighbor() != nullptr) {
|
|
hcell = row->at(++pos_le);
|
|
cells = &hcell.getRect();
|
|
|
|
SCell* u = fi.getNeighbor();
|
|
|
|
int nbr_cpr = input_irgrid3d_ptr->getLayerCount();
|
|
int cid_pos = (u->getCellId()) % nbr_cpr;
|
|
pos_fr = cid_pos == 0 ? nbr_cpr-1 : cid_pos-1;
|
|
|
|
cellIdx = pos_fr-1;
|
|
|
|
} else if (ri <= hcell.getValTo() ||
|
|
fi.getNeighbor() == nullptr) {
|
|
if (to > vCell.getValTo() && begin_i.getUpper() != nullptr) {
|
|
SCell* up = begin_i.getUpper();
|
|
|
|
int nbr_cpr = input_irgrid3d_ptr->getLayerCount();
|
|
int cid_pos = (up->getCellId()) % nbr_cpr;
|
|
pos_fr = cid_pos == 0 ? nbr_cpr-1 : cid_pos-1;
|
|
|
|
|
|
cellIdx = pos_fr-1;
|
|
int pos_test = pos_bo +1;
|
|
if(pos_test < (int)col->size()) {
|
|
row = &col->at(++pos_bo).getRow(); // one row up
|
|
hcell = row->at(pos_left);
|
|
cells = &hcell.getRect();
|
|
begin_i = cells->at(pos_fr);
|
|
// in case there is another neighbor in the new row
|
|
pos_le = pos_left;
|
|
}
|
|
|
|
} else if (to <= vCell.getValTo() &&
|
|
begin_i.getUpper() == nullptr) {
|
|
break;
|
|
} else { break; }
|
|
}
|
|
}
|
|
cellIdx++;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Value mapping function of operator ~cellnos\_ir~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid3dValueMapCellnos( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
IrregularGrid3D *input_irgrid3d_ptr
|
|
= static_cast<IrregularGrid3D*>( args[0].addr );
|
|
|
|
Rectangle<3> *search_window_ptr
|
|
= static_cast<Rectangle<3>*>( args[1].addr );
|
|
|
|
if (input_irgrid3d_ptr != nullptr && search_window_ptr != nullptr) {
|
|
|
|
std::set<int> cell_ids;
|
|
|
|
result = qp->ResultStorage(s);
|
|
collection::IntSet* res = (collection::IntSet*) result.addr;
|
|
|
|
Rectangle<3> * b_box = input_irgrid3d_ptr->getBoundingBox();
|
|
if(b_box->getMinX() > b_box->getMaxX() ||
|
|
b_box->getMinY() > b_box->getMaxY()
|
|
||b_box->getMinZ() > b_box->getMaxZ())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!search_window_ptr->Intersects(*b_box)) {
|
|
cell_ids.insert(0);
|
|
res->setTo(cell_ids);
|
|
return 0;
|
|
}
|
|
|
|
// 'truncate' search window in case of partial cutting
|
|
if (!b_box->Contains(*search_window_ptr)) {
|
|
search_window_ptr = new Rectangle<3>(
|
|
search_window_ptr->Intersection(*b_box));
|
|
|
|
cell_ids.insert(0);
|
|
}
|
|
|
|
cellNum(input_irgrid3d_ptr, search_window_ptr, &cell_ids);
|
|
|
|
res->setTo(cell_ids);
|
|
|
|
return 0;
|
|
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
Value mapping function of operator ~scc\_3d~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid3dValueMapSCC( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
IrregularGrid3D *input_irgrid3d_ptr
|
|
= static_cast<IrregularGrid3D*>( args[0].addr );
|
|
|
|
Rectangle<3> *search_window_ptr
|
|
= static_cast<Rectangle<3>*>( args[1].addr );
|
|
|
|
Rectangle<3> *search_window_ptr_2
|
|
= static_cast<Rectangle<3>*>( args[2].addr );
|
|
|
|
CcInt* cellno_ptr = static_cast<CcInt*>(args[3].addr);
|
|
int cellno = cellno_ptr->GetIntval();
|
|
|
|
if (input_irgrid3d_ptr != nullptr && search_window_ptr != nullptr
|
|
&& search_window_ptr_2 != nullptr) {
|
|
|
|
std::set<int> cell_ids;
|
|
std::set<int> cell_ids_2;
|
|
|
|
Rectangle<3>* b_box = input_irgrid3d_ptr->getBoundingBox();
|
|
if (!search_window_ptr->Intersects(*b_box)
|
|
|| !search_window_ptr_2->Intersects(*b_box)) {
|
|
return 0;
|
|
}
|
|
|
|
// 'truncate' search window in case of partial cutting
|
|
if (!b_box->Contains(*search_window_ptr)) {
|
|
search_window_ptr = new Rectangle<3>(
|
|
search_window_ptr->Intersection(*b_box));
|
|
|
|
cell_ids.insert(0);
|
|
}
|
|
|
|
if (!b_box->Contains(*search_window_ptr_2)) {
|
|
search_window_ptr_2 = new Rectangle<3>(
|
|
search_window_ptr_2->Intersection(*b_box));
|
|
|
|
cell_ids_2.insert(0);
|
|
}
|
|
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
bool boolval = false;
|
|
|
|
cellNum(input_irgrid3d_ptr, search_window_ptr, &cell_ids);
|
|
cellNum(input_irgrid3d_ptr, search_window_ptr_2, &cell_ids_2);
|
|
|
|
std::vector<int> v(sizeof(cell_ids)+ sizeof(cell_ids_2));
|
|
std::vector<int>::iterator it;
|
|
|
|
it=std::set_intersection (cell_ids.begin(), cell_ids.end(),
|
|
cell_ids_2.begin(), cell_ids_2.end(), v.begin());
|
|
v.resize(it-v.begin());
|
|
|
|
if(v.empty()) {
|
|
//no intersection between rectangles
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
|
|
if(v.at(0) == cellno)
|
|
{
|
|
boolval = true;
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/*
|
|
Value Mapping function of operator ~getCell~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid3dValueMapGetCell(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
|
|
IrregularGrid3D *input_irgrid3d_ptr
|
|
= static_cast<IrregularGrid3D*>( args[0].addr );
|
|
|
|
CcInt* cellno_ptr = static_cast<CcInt*>(args[1].addr);
|
|
int cellno = cellno_ptr->GetIntval();
|
|
|
|
if (input_irgrid3d_ptr != nullptr)
|
|
{
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<3> *res = (Rectangle<3>*) result.addr;
|
|
|
|
std::vector<VCell3D>* column = &input_irgrid3d_ptr->getColumnVector();
|
|
for(size_t i = 0; i < column->size(); i++)
|
|
{
|
|
VCell3D vCell = column->at(i);
|
|
std::vector<HCell3D>* row = &vCell.getRow();
|
|
for(size_t ii=0; ii < row->size(); ii++)
|
|
{
|
|
HCell3D hCell = row->at(ii);
|
|
std::vector<SCell>* cell = &hCell.getRect();
|
|
for(size_t iii=0; iii < cell->size(); iii++)
|
|
{
|
|
SCell c = cell->at(iii);
|
|
if(cellno == c.getCellId())
|
|
{
|
|
double min[3], max[3];
|
|
min[0] = hCell.getValFrom();
|
|
min[1] = vCell.getValFrom();
|
|
min[2] = c.getValFrom();
|
|
max[0] = hCell.getValTo();
|
|
max[1] = vCell.getValTo();
|
|
max[2] = c.getValTo();
|
|
res->Set(true, min, max);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
Value mapping function of operator ~bbox\_grid~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid2dValueMapBBox( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
|
|
Stream<Rectangle<2>> rStream(args[0]);
|
|
result = qp->ResultStorage(s);
|
|
Rectangle<2>* res = (Rectangle<2>*) result.addr;
|
|
|
|
|
|
rStream.open();
|
|
Rectangle<2>* next = rStream.request();
|
|
|
|
if(next != 0) {
|
|
double min[2], max[2];
|
|
min[0] = next->getMinX();
|
|
min[1] = next->getMinY();
|
|
max[0] = next->getMaxX();
|
|
max[1] = next->getMaxY();
|
|
next = rStream.request();
|
|
|
|
while(next != 0){
|
|
if(next->getMinX() < min[0])
|
|
{ min[0] = next->getMinX(); }
|
|
if(next->getMinY() < min[1])
|
|
{ min[1] = next->getMinY(); }
|
|
if(next->getMaxX() > max[0])
|
|
{ max[0] = next->getMaxX(); }
|
|
if(next->getMaxY() > max[1])
|
|
{ max[1] = next->getMaxY(); }
|
|
|
|
next = rStream.request();
|
|
}
|
|
|
|
rStream.close();
|
|
|
|
res->Set(true, min, max);
|
|
|
|
return 0;
|
|
}
|
|
return -1;
|
|
|
|
}
|
|
|
|
/*
|
|
Value mapping function of operator ~bbox\_grid3d~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid3D::IrGrid3dValueMapBBox( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
|
|
Stream<Rectangle<3>> rStream(args[0]);
|
|
result = qp->ResultStorage(s);
|
|
Rectangle<3>* res = (Rectangle<3>*) result.addr;
|
|
|
|
rStream.open();
|
|
Rectangle<3>* next = rStream.request();
|
|
if(next != 0) {
|
|
double min[3], max[3];
|
|
min[0] = next->getMinX();
|
|
min[1] = next->getMinY();
|
|
min[2] = next->getMinZ();
|
|
max[0] = next->getMaxX();
|
|
max[1] = next->getMaxY();
|
|
max[2] = next->getMaxZ();
|
|
|
|
next = rStream.request();
|
|
|
|
while(next != 0){
|
|
if(next->getMinX() < min[0])
|
|
{ min[0] = next->getMinX(); }
|
|
if(next->getMinY() < min[1])
|
|
{ min[1] = next->getMinY(); }
|
|
if(next->getMinZ() < min[2])
|
|
{ min[2] = next->getMinZ(); };
|
|
if(next->getMaxX() > max[0])
|
|
{ max[0] = next->getMaxX(); }
|
|
if(next->getMaxY() > max[1])
|
|
{ max[1] = next->getMaxY(); }
|
|
if(next->getMaxZ() > max[2])
|
|
{ max[2] = next->getMaxZ(); }
|
|
|
|
next = rStream.request();
|
|
}
|
|
rStream.close();
|
|
|
|
res->Set(true, min, max);
|
|
|
|
return 0;
|
|
}
|
|
return -1;
|
|
} |