Files
secondo/Algebras/Flock/OctreeDatParser.cpp

502 lines
13 KiB
C++
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of 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
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] The file is originally provided by Thomas Wolle, and integrated into SECONDO
by Mahmoud Sakr
June, 2009 Mahmoud Sakr
[TOC]
*/
#ifndef OCTREE_PARSER_SOURCE
#define OCTREE_PARSER_SOURCE
#include <fstream>
#include <assert.h>
#include <iostream>
#include <vector>
#include <map>
#include <cstdlib>
#include <cmath>
#include "OctreeDatParser.h"
#include "OctreeElements.h"
#include "satof.h"
//#define SHOW_DEBUG 1
using namespace std;
OctreeDatParser::OctreeDatParser(char* inputFileName, int startCol, int endCol)
{
this->activeTrajectories=0;
#ifdef SHOW_DEBUG
::std::cout << "About to parse the file: " << inputFileName << '\n';
::std::cout << "Start Column: " << startCol << "\tEnd Column: " << endCol
<< '\n';
#endif
// set up the vars
this->tmpArray = new char[16];
int index = 0;
this->timesteps = endCol-startCol;
this->inputFile.open(inputFileName, std::ios::in);
// parse the general tree specs
while (inputFile.get(this->tmpArray[index])){
if (this->tmpArray[index]=='\n' || this->tmpArray[index]==':'){
this->tmpArray[index]='\0';
#ifdef SHOW_DEBUG
::std::cout << "found string: " << this->tmpArray << '\n';
#endif
if (strcmp(this->tmpArray, "dimensions") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "setting dimensions in parser" << '\n';
#endif
this->dimensions = this->getNextNumber();
} else if (strcmp(this->tmpArray, "extent") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "setting extent in parser" << '\n';
#endif
this->extent= new double[this->dimensions * 2];
for(int i=0; i< this->dimensions * 2 ; ++i)
this->extent[i] = this->getNextDouble();
// }
// else if (strcmp(this->tmpArray, "timesteps") == 0) {
//#ifdef SHOW_DEBUG
// ::std::cout << "setting timesteps in parser" << '\n';
//#endif
// this->timesteps = this->getNextNumber();
} else if (strcmp(this->tmpArray, "details") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "turning to details in parser" << '\n';
#endif
assert(this->dimensions > 0);
assert(this->timesteps > 0);
break;
}
index=-1;
}
index++;
}
this->pointData = new vector<OctreePoint*>();
#ifdef SHOW_DEBUG
::std::cout << "parsing point information" << '\n';
#endif
index=0;
// parse the point information and insert to the tree!
while (inputFile.get(this->tmpArray[index])){
if (this->tmpArray[index]=='\n' || this->tmpArray[index]==':'){
this->tmpArray[index]='\0';
#ifdef SHOW_DEBUG
::std::cout << "found string: " << this->tmpArray << '\n';
#endif
if (strcmp(this->tmpArray, "obj") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "adding point to list" << '\n';
#endif
OctreePoint* tmp = this->createPoint(startCol, endCol);
if(tmp != 0) this->pointData->push_back(tmp);
#ifdef SHOW_DEBUG
::std::cout << "Coordinates: " ; tmp->printCoordinates();
#endif
}
index=-1;
}
index++;
}
#ifdef SHOW_DEBUG
printf("pointData contains %d points.\n", pointData->size());
#endif
this->inputFile.close();
};
OctreeDatParser::OctreeDatParser(char* inputFileName){
#ifdef SHOW_DEBUG
::std::cout << "About to parse the file: " << inputFileName << '\n';
#endif
// set up the vars
this->tmpArray = new char[16];
int index = 0;
this->inputFile.open(inputFileName, std::ios::in);
// parse the general tree specs
while (inputFile.get(this->tmpArray[index])){
if (this->tmpArray[index]=='\n' || this->tmpArray[index]==':'){
this->tmpArray[index]='\0';
#ifdef SHOW_DEBUG
::std::cout << "found string: " << this->tmpArray << '\n';
#endif
if (strcmp(this->tmpArray, "dimensions") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "setting dimensions in parser" << '\n';
#endif
this->dimensions = this->getNextNumber();
} else if (strcmp(this->tmpArray, "extent") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "setting extent in parser" << '\n';
#endif
this->extent= new double[this->dimensions * 2];
for(int i=0; i< this->dimensions * 2 ; ++i)
this->extent[i] = this->getNextDouble();
} else if (strcmp(this->tmpArray, "timesteps") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "setting timesteps in parser" << '\n';
#endif
this->timesteps = this->getNextNumber();
} else if (strcmp(this->tmpArray, "details") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "turning to details in parser" << '\n';
#endif
assert(this->dimensions > 0);
assert(this->timesteps > 0);
break;
}
index=-1;
}
index++;
}
this->pointData = new vector<OctreePoint*>();
#ifdef SHOW_DEBUG
::std::cout << "parsing point information" << '\n';
#endif
index=0;
// parse the point information and insert to the tree!
while (inputFile.get(this->tmpArray[index])){
if (this->tmpArray[index]=='\n' || this->tmpArray[index]==':'){
this->tmpArray[index]='\0';
#ifdef SHOW_DEBUG
::std::cout << "found string: " << this->tmpArray << '\n';
#endif
if (strcmp(this->tmpArray, "obj") == 0) {
#ifdef SHOW_DEBUG
::std::cout << "adding point to list" << '\n';
#endif
OctreePoint* tmp = this->createPoint();
this->pointData->push_back(tmp);
#ifdef SHOW_DEBUG
::std::cout << "Coordinates: " ; tmp->printCoordinates();
#endif
}
index=-1;
}
index++;
}
#ifdef SHOW_DEBUG
printf("pointData contains %d points.\n", pointData->size());
#endif
this->inputFile.close();
};
OctreeDatParser::~OctreeDatParser(){
// delete all points in the pointData set
::std::vector<OctreePoint*>::iterator pointIterator;
for(pointIterator=this->pointData->begin(); pointIterator!=
this->pointData->end(); pointIterator++){
OctreePoint* point = *pointIterator;
delete point;
}
delete this->pointData;
delete[] this->tmpArray;
delete[] this->extent;
};
::std::vector<OctreePoint*>*
OctreeDatParser::getPointset(){
return this->pointData;
}
::std::map<int, OctreeCell*>*
OctreeDatParser::getSkiptree4Dim(){
int tmpTimesteps = this->timesteps;
this->timesteps = 4;
::std::map<int, OctreeCell*>* skiptree =
this->getSkiptree();
this->timesteps = tmpTimesteps;
return skiptree;
}
::std::map<int, OctreeCell*>*
OctreeDatParser::getSkiptreeFromSet(::std::vector<OctreePoint*>* pointSet,
int pointDimensions){
::std::vector<OctreePoint*>* tmpPointData = this->pointData;
this->pointData = pointSet;
::std::map<int, OctreeCell*>* skiptree =
this->getSkiptree();
this->pointData = tmpPointData;
return skiptree;
}
double OctreeDatParser::calcHalfSideLength()
{
double max=0, diff=0;
for(int i= 0; i<this->dimensions; ++i)
{
diff= abs(extent[i] - extent[i+this->dimensions]);
max= (diff > max) ? diff: max;
}
return max;
}
void OctreeDatParser::calcSkipTreeCoords(double* res)
{
for(int i= 0; i<this->timesteps; ++i)
{
for(int k= 0; k< this->dimensions; ++k)
res[k + i* this->dimensions]=
(this->extent[k] + this->extent[k + this->dimensions])/2;
}
}
::std::map<int, OctreeCell*>*
OctreeDatParser::getSkiptree(){
assert(this->pointData->size() > 0);
// init the tree data
double* treeCoords = new double[this->dimensions*this->timesteps];
double halfSideLength = this->calcHalfSideLength();
this->calcSkipTreeCoords(treeCoords);
// init random numbers.
srand(time(NULL));
::std::map<int, ::std::vector<OctreePoint*>*> skipTreeSets;
vector<OctreePoint*>::iterator pointIterator;
int nextIndex = 0;
for(pointIterator=this->pointData->begin(); pointIterator!=
this->pointData->end(); pointIterator++){
for (int index=0;; index++){
if(rand()%2 == 0){
// init all new sets, if there were none!
while(nextIndex <= index){
::std::vector<OctreePoint*> *testvec =
new ::std::vector<OctreePoint*>();
skipTreeSets[nextIndex++] = testvec;
}
skipTreeSets[index]->push_back(*pointIterator);
break;
}
}
}
#ifdef SHOW_DEBUG
printf("Number of sets is %d, numbers in each set are:\n", nextIndex);
for(int i=0; i<nextIndex; i++)
printf("Set %d contains %d points\n", i, skipTreeSets[i]->size());
#endif
#ifdef SHOW_DEBUG
::std::cout << "initializing octrees" << '\n';
#endif
// init the last tree
::std::map<int, OctreeCell*>* treeMap = new ::std::map<int, OctreeCell*>();
(*treeMap)[nextIndex-1] = new OctreeCell(this->dimensions*this->timesteps,
treeCoords, halfSideLength);
// insert points from last set
for(pointIterator=skipTreeSets[nextIndex-1]->begin();
pointIterator!=skipTreeSets[nextIndex-1]->end(); pointIterator++){
(*treeMap)[nextIndex-1]->insert(*pointIterator);
}
#ifdef SHOW_DEBUG
printf("Inserted %d points into skiptree no. %d\n",
(*treeMap)[nextIndex-1]->getPointsContained(), nextIndex-1);
#endif
for(int i=nextIndex-2; i>=0; i--){
(*treeMap)[i] = (OctreeCell*)(*treeMap)[i+1]->getSkipTreeCopy();
OctreeCell* tmpCell = (*treeMap)[i];
for(pointIterator=skipTreeSets[i]->begin(); pointIterator!=
skipTreeSets[i]->end(); pointIterator++){
tmpCell->insert(*pointIterator);
}
//delete the list here
delete skipTreeSets[i];
#ifdef SHOW_DEBUG
printf("Inserted %d points into skiptree no. %d\n",
tmpCell->getPointsContained(), i);
#endif
}
// do some cleanups
delete[] treeCoords;
#ifdef SHOW_DEBUG
::std::cout << "handing over new octree" << '\n';
#endif
return treeMap;
};
OctreePoint*
OctreeDatParser::createPoint(){
OctreePoint *newPoint;
double *pointCoords = new double[this->dimensions*this->timesteps];
int ident = getNextNumber();
for (int index=0; index < this->dimensions*this->timesteps; index++){
pointCoords[index] = this->getNextDouble();
}
newPoint = new OctreePoint(this->dimensions*this->timesteps,
pointCoords, ident);
delete[] pointCoords;
return newPoint;
};
OctreePoint*
OctreeDatParser::createPoint(int startCol, int endCol){
//bool debugme=true;
OctreePoint *newPoint=0;
int ident = getNextNumber();
int cnt = getNextNumber();
if(cnt < endCol +1 ) return newPoint;
this->activeTrajectories++;
//skip the coordinates before startCol
double tmp;
bool defined=false;
for (int index=0; index < this->dimensions * startCol; index++)
this->getNextCoord(tmp);
//read the specified part of the trajectory
assert( (endCol-startCol) > 0);
double *pointCoords = new double[(endCol-startCol)* this->dimensions];
for (int index=0; index < this->dimensions * (endCol - startCol ) ; ++index)
{
defined = this->getNextCoord(tmp);
if(defined) pointCoords[index]= tmp; else break;
}
if(defined)
newPoint = new OctreePoint(this->dimensions * this->timesteps,
pointCoords, ident);
delete[] pointCoords;
return newPoint;
};
OctreeCell*
OctreeDatParser::getOctree(){
// init the tree data
double* treeCoords = new double[this->dimensions*this->timesteps];
double halfSideLength = this->calcHalfSideLength();
this->calcSkipTreeCoords(treeCoords);
// init the tree
OctreeCell* octree = new OctreeCell(this->dimensions*this->timesteps,
treeCoords, halfSideLength);
// insert the points
::vector<OctreePoint*>::iterator pointIterator = this->pointData->begin();
for(; pointIterator!=this->pointData->end(); pointIterator++){
octree->insert(*pointIterator);
}
delete[] treeCoords;
return octree;
};
int
OctreeDatParser::getNextNumber(){
char* tmp = new char[20];
int index=0;
while (inputFile.get(tmp[index]))
{
if (tmp[index]=='\n' || tmp[index]==':')
break;
++index;
}
tmp[index]='\0';
int res = atoi (tmp);
delete[] tmp;
return res;
}
bool
OctreeDatParser::getNextCoord(double& res){
char* tmp = new char[20];
int index=0;
while (inputFile.get(tmp[index]))
{
if (tmp[index]=='\n' || tmp[index]==':')
break;
++index;
}
tmp[index]='\0';
if(strcmp(tmp, "undef") == 0 )
{
delete[] tmp;
return false;
}
res= satof(tmp);
delete[] tmp;
return true;
}
double
OctreeDatParser::getNextDouble(){
char* tmp = new char[20];
int index=0;
while (inputFile.get(tmp[index]))
{
if (tmp[index]=='\n' || tmp[index]==':')
break;
++index;
}
tmp[index]='\0';
double res= satof(tmp);
delete[] tmp;
return res;
}
int
OctreeDatParser::activeTrajectoriesCount()
{
return this->activeTrajectories;
}
#endif // OCTREE_PARSER_SOURCE