00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <structureColoring/grids/GridMap.h>
00037 #include <structureColoring/histograms/OutOfRangeException.h>
00038
00039
00040
00041 GridMap::GridMap(const GridMap& gridMap, float xMin, float xMax, float yMin, float yMax,
00042 unsigned int xOff, unsigned int xAdd, unsigned int yOff, unsigned int yAdd,
00043 float cellSize)
00044 :PositionedGrid2D<NodeGridCell>(gridMap.getPlane3D(), xMin, xMax, yMin, yMax, cellSize){
00045 if(gridMap.getXMin() < xMin || gridMap.getXMax() > xMax
00046 || gridMap.getYMin() < yMin || gridMap.getYMax() > yMax){
00047
00048
00049 throw OutOfRangeException("Min and Max (x and y) have to include gridMap");
00050 }
00051
00052
00053
00054
00055 float scale = round(gridMap.getCellSize() / cellSize);
00056 unsigned int regionSize = scale +0.5f;
00057
00058 if (regionSize == 0)
00059 {
00060
00061 printf("scale: %f, oldCellSize: %f, newCellSize: %f", scale, gridMap.getCellSize(),cellSize);
00062 regionSize = 1;
00063 }
00064 for (unsigned int i = 0; i < gridMap.getWidth(); i++) {
00065 for (unsigned int j = 0; j < gridMap.getHeight(); j++) {
00066 if (!gridMap.Grid2D<NodeGridCell>::operator()(i, j).populated())
00067 continue;
00068 unsigned int newX = static_cast<unsigned int> ((float(xOff) + scale * float(i)) +0.5f);
00069 unsigned int newY = static_cast<unsigned int> ((float(yOff) + scale * float(j)) +0.5f);
00070 for (unsigned int k = 0; k < regionSize; ++k) {
00071 if (newX + k >= mWidth)
00072 continue;
00073 for (unsigned int l = 0; l < regionSize; ++l) {
00074 if (newY + l >= mHeight)
00075 continue;
00076 this->Grid2D<NodeGridCell>::operator()(newX + k, newY + l).blindPopulate();
00077 }
00078 }
00079 }
00080 }
00081
00082 mGridCCStartPos.first += xOff;
00083 mGridCCStartPos.second += yOff;
00084 }
00085
00086 void GridMap::pushPopulatedUnvisitedNeighbors(std::queue<std::pair<unsigned int, unsigned int> >& neighbors, const unsigned int& width, const unsigned int& height) const{
00087 assert((width<mWidth)&&(height<mHeight));
00088
00089 if(width > 0){
00090 std::pair<unsigned int, unsigned int> n = std::make_pair(width-1, height);
00091 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00092 neighbors.push(n);
00093 }
00094 }
00095 if(width < mWidth-1){
00096 std::pair<unsigned int, unsigned int> n = std::make_pair(width+1, height);
00097 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00098 neighbors.push(n);
00099 }
00100 }
00101 if(height > 0){
00102 std::pair<unsigned int, unsigned int> n = std::make_pair(width, height-1);
00103 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00104 neighbors.push(n);
00105 }
00106 }
00107 if(height < mHeight-1){
00108 std::pair<unsigned int, unsigned int> n = std::make_pair(width, height+1);
00109 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00110 neighbors.push(n);
00111 }
00112 }
00113
00114 if(width > 0 && height > 0){
00115 std::pair<unsigned int, unsigned int> n = std::make_pair(width-1, height-1);
00116 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00117 neighbors.push(n);
00118 }
00119 }
00120 if(width < mWidth-1 && height > 0){
00121 std::pair<unsigned int, unsigned int> n = std::make_pair(width+1, height-1);
00122 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00123 neighbors.push(n);
00124 }
00125 }
00126 if(width > 0 && height < mHeight-1){
00127 std::pair<unsigned int, unsigned int> n = std::make_pair(width-1, height+1);
00128 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00129 neighbors.push(n);
00130 }
00131 }
00132 if(width < mWidth-1 && height < mHeight-1){
00133 std::pair<unsigned int, unsigned int> n = std::make_pair(width+1, height+1);
00134 if((!mGrid[getIndex(n.first, n.second, mWidth)].visited()) && (mGrid[getIndex(n.first, n.second, mWidth)].populated())){
00135 neighbors.push(n);
00136 }
00137 }
00138 }
00139
00140
00141
00142 void GridMap::print() const{
00143 std::cout << "printing grid, width = " << mWidth << " height = " << mHeight << std::endl;
00144 for(unsigned int h = 0; h < mHeight; h++){
00145 std::cout << "|";
00146 for(unsigned int w = 0; w < mWidth; w++){
00147 if (mGrid[getIndex(w, h, mWidth)].populated()) std::cout << "x|";
00148 else std::cout << "-|";
00149 }
00150 std::cout << std::endl;
00151 }
00152 }
00153
00154 void GridMap::print(const std::pair<unsigned int, unsigned int>& coords) const{
00155 std::cout << "printing grid, width = " << mWidth << " height = " << mHeight << std::endl;
00156 for(unsigned int h = 0; h < mHeight; h++){
00157 std::cout << "|";
00158 for(unsigned int w = 0; w < mWidth; w++){
00159 if (mGrid[getIndex(w, h, mWidth)].populated())
00160 if(w == coords.first && h == coords.second)
00161 std::cout << "O|";
00162 else std::cout << "x|";
00163 else if(w == coords.first && h == coords.second)
00164 std::cout << "O|";
00165 else std::cout << "-|";
00166 }
00167 std::cout << std::endl;
00168 }
00169 std::cout << coords.first << " " << coords.second << std::endl;
00170 }
00171
00172
00173
00174 void GridMap::startConnectedComponentAt(ConnectedComponent& ccc, const Indices& startPos) {
00175 std::queue<Indices> neighborsQueue;
00176 assert((startPos.first < getWidth()) && (startPos.second < getHeight()));
00177 if ((!(*this)(startPos.first, startPos.second).visited()) && ((*this)(startPos.first, startPos.second).populated())) {
00178 neighborsQueue.push(startPos);
00179 }
00180 while (!neighborsQueue.empty()) {
00181 Indices xy = neighborsQueue.front();
00182 neighborsQueue.pop();
00183 if ((!((*this)(xy.first, xy.second).visited())) && ((*this)(xy.first, xy.second).populated())) {
00184
00185 pushPopulatedUnvisitedNeighbors(neighborsQueue, xy.first, xy.second);
00186
00187 (*this)(xy.first, xy.second).visit();
00188 ccc.addCell(xy);
00189 for (std::vector<unsigned int>::const_iterator pop_it = (*this)(xy.first, xy.second).getPopulation().begin(); pop_it
00190 != (*this)(xy.first, xy.second).getPopulation().end(); pop_it++) {
00191 ccc.addNumberOfPoints(1);
00192 }
00193 }
00194 }
00195 }
00196
00197
00198
00199 void GridMap::checkNodesAgainstGridConnection(NodeIndices& outNodeIndices, const NodePointers& inNodeCandidates, float newCellSize,
00200 unsigned int minNodesCount) const {
00201 float xMin = 0.f, yMin = 0.f, xMax = 0.f, yMax = 0.f;
00202 unsigned int xOff = 0, xAdd = 0, yOff = 0, yAdd = 0;
00203 float nodeXMin = std::numeric_limits<float>::max();
00204 float nodeXMax = -std::numeric_limits<float>::max();
00205 float nodeYMin = std::numeric_limits<float>::max();
00206 float nodeYMax = -std::numeric_limits<float>::max();
00207 outNodeIndices.reserve(inNodeCandidates.size());
00208 for(NodePointers::const_iterator nit = inNodeCandidates.begin(); nit != inNodeCandidates.end(); ++nit){
00209 Vec3 tPos(this->getPlane3D().transformToXYPlane((*nit)->value_.meanPos));
00210 if(tPos.x() < nodeXMin) nodeXMin = tPos.x();
00211 if(tPos.x() > nodeXMax) nodeXMax = tPos.x();
00212 if(tPos.y() < nodeYMin) nodeYMin = tPos.y();
00213 if(tPos.y() > nodeYMax) nodeYMax = tPos.y();
00214 }
00215 this->getNewExtremes(xMin, xMax, yMin, yMax, xOff, xAdd, yOff, yAdd, nodeXMin, nodeXMax, nodeYMin, nodeYMax, newCellSize);
00216 GridMap testGrid(*this, xMin, xMax, yMin, yMax, xOff, xAdd, yOff, yAdd, newCellSize);
00217 testGrid.calculateStartPos();
00218
00219 testGrid.populate(inNodeCandidates);
00220
00221
00222 ConnectedComponent ccc;
00223 testGrid.startConnectedComponentAt(ccc, testGrid.getStartPos());
00224 if (ccc.getNumPoints() > minNodesCount) {
00225 testGrid.gatherNodesInCC(outNodeIndices, ccc);
00226 }
00227 }
00228
00229
00230
00231 void GridMap::gatherNodesInCC(NodePointers& outputNodes, const ConnectedComponent& conComp, const NodePointers& octreeNodes) const {
00232 for (unsigned int l = 0; l < conComp.getCells().size(); l++) {
00233 const uints& gridPopulation = (*this)(conComp.getCells()[l].first, conComp.getCells()[l].second).getPopulation();
00234 for (unsigned int j = 0; j < gridPopulation.size(); ++j) {
00235 const unsigned int& node_idx = gridPopulation[j];
00236 assert(node_idx < octreeNodes.size());
00237 outputNodes.push_back(octreeNodes[node_idx]);
00238 }
00239 }
00240 }
00241
00242
00243
00244 void GridMap::gatherNodesInCC(NodeIndices& outputIndices, const ConnectedComponent& conComp) const {
00245 for (unsigned int l = 0; l < conComp.getCells().size(); l++) {
00246 const uints& gridPopulation = (*this)(conComp.getCells()[l].first, conComp.getCells()[l].second).getPopulation();
00247 for (unsigned int j = 0; j < gridPopulation.size(); ++j) {
00248 const unsigned int& node_idx = gridPopulation[j];
00249 outputIndices.push_back(node_idx);
00250 }
00251 }
00252 }
00253
00254
00255
00256 void GridMap::getConnectedComponentsAndNotConnectedNodes(NodePointersVec& nodesInCC, const NodePointers& inputOctreeNodes, float cellSize,
00257 unsigned int minPlaneNodes, unsigned int minCCNodes, NodePointers* notConnectedNodesOutput){
00258
00259
00260 ConnectedComponent ccc;
00261 this->startConnectedComponentAt(ccc, getStartPos());
00262 if (ccc.getNumPoints() > minPlaneNodes) {
00263 if (ccc.getNumPoints() > minCCNodes) {
00264 NodePointers ccNodes;
00265 this->gatherNodesInCC(ccNodes, ccc, inputOctreeNodes);
00266 nodesInCC.push_back(ccNodes);
00267 } else {
00268
00269 if (notConnectedNodesOutput)
00270 this->gatherNodesInCC(*notConnectedNodesOutput, ccc, inputOctreeNodes);
00271 }
00272 }
00273 ccc.reset();
00274 for (unsigned int i = 0; i < mWidth; i++) {
00275 for (unsigned int j = 0; j < mHeight; j++) {
00276 this->startConnectedComponentAt(ccc, std::make_pair(i, j));
00277 if (ccc.getNumPoints() > std::min(minPlaneNodes, minCCNodes)) {
00278 NodePointers ccNodes;
00279 this->gatherNodesInCC(ccNodes, ccc, inputOctreeNodes);
00280 nodesInCC.push_back(ccNodes);
00281 } else {
00282
00283 if (notConnectedNodesOutput)
00284 this->gatherNodesInCC(*notConnectedNodesOutput, ccc, inputOctreeNodes);
00285 }
00286 ccc.reset();
00287 }
00288 }
00289
00290 }
00291
00292
00293
00294 void GridMap::getNewExtremes(float& xMinOut, float& xMaxOut, float& yMinOut, float& yMaxOut,
00295 unsigned int& xOff, unsigned int& xAdd, unsigned int& yOff, unsigned int& yAdd,
00296 float xMinIn, float xMaxIn, float yMinIn, float yMaxIn, float stepSize) const {
00297 xOff = xAdd = yOff = yAdd = 0;
00298 if (mXMin > xMinIn){
00299 xOff = std::ceil((mXMin - xMinIn) / stepSize);
00300 xMinOut = mXMin - xOff * stepSize;
00301 } else {
00302 xMinOut = mXMin;
00303 }
00304 if (mXMax < xMaxIn){
00305 xAdd = std::ceil((xMaxIn - mXMax) / stepSize);
00306 xMaxOut = mXMax + xAdd * stepSize;
00307 } else {
00308 xMaxOut = mXMax;
00309 }
00310 if (mYMin > yMinIn){
00311 yOff = std::ceil((mYMin - yMinIn) / stepSize);
00312 yMinOut = mYMin - yOff * stepSize;
00313 } else {
00314 yMinOut = mYMin;
00315 }
00316 if (mYMax < yMaxIn){
00317 yAdd = std::ceil((yMaxIn - mYMax) / stepSize);
00318 yMaxOut = mYMax + yAdd * stepSize;
00319 } else {
00320 yMaxOut = mYMax;
00321 }
00322
00323
00324
00325
00326 }
00327
00328
00329
00330
00331 void GridMap::calculateStartPos(){
00332 for(unsigned int w=0; w<mWidth; w++){
00333 for(unsigned int h=0; h<mHeight; h++){
00334 if((*this)(w, h).populated()){
00335 mGridCCStartPos = std::make_pair(w, h);
00336 return;
00337 }
00338 }
00339 }
00340 assert(false);
00341 }