You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
5.9 KiB
C++

/**
* @file
* @brief Representation of a 3D point type
* @author Jan Elsberg. Automation Group, Jacobs University Bremen gGmbH, Germany.
*/
#ifndef __POINT_TYPE_H__
#define __POINT_TYPE_H__
#include "point.h"
#include "data_types.h"
#include <string>
using std::string;
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include <iostream>
#include <fstream>
#include <string.h>
class Scan;
class PointType {
public:
static const unsigned int USE_NONE;
static const unsigned int USE_REFLECTANCE;
static const unsigned int USE_NORMAL;
static const unsigned int USE_TEMPERATURE;
static const unsigned int USE_AMPLITUDE;
static const unsigned int USE_DEVIATION;
static const unsigned int USE_HEIGHT;
static const unsigned int USE_TYPE;
static const unsigned int USE_COLOR;
static const unsigned int USE_TIME;
static const unsigned int USE_INDEX;
PointType();
PointType(unsigned int _types);
bool hasReflectance();
bool hasNormal();
bool hasTemperature();
bool hasAmplitude();
bool hasDeviation();
bool hasType();
bool hasColor();
bool hasTime();
bool hasIndex();
unsigned int getReflectance();
unsigned int getTemperature();
unsigned int getAmplitude();
unsigned int getDeviation();
unsigned int getTime();
unsigned int getIndex();
unsigned int getType();
unsigned int getType(unsigned int type);
unsigned int getPointDim();
static PointType deserialize(std::ifstream &f);
void serialize(std::ofstream &f);
unsigned int toFlags() const;
template <class T>
T *createPoint(const Point &P, unsigned int index=0);
template <class T>
Point createPoint(T *p);
//! Aquire DataPointer objects from \a scan, determined by its types
void useScan(Scan* scan);
//! Release the DataPointer objects
void clearScan();
//! Create a point with attributes via the DataPointers from the scan
template<typename T>
T* createPoint(unsigned int i, unsigned int index = 0);
//! Create an array with coordinate+attribute array per point with transfer of ownership
template<typename T>
T** createPointArray(Scan* scan);
private:
/**
* collection of flags
*/
unsigned int types;
/**
* Derived from types: 3 spatial dimensions + 1 for each flag set
**/
unsigned int pointdim;
/**
* Stores the size of each point in bytes
**/
unsigned int pointbytes;
/**
* Derived from types, to map type to the array index for each point
**/
int dimensionmap[9];
bool hasType(unsigned int type);
unsigned int getScanSize(Scan* scan);
DataXYZ* m_xyz;
DataXYZ* m_normal;
DataRGB* m_rgb;
DataReflectance* m_reflectance;
DataTemperature* m_temperature;
DataAmplitude* m_amplitude;
DataType* m_type;
DataDeviation* m_deviation;
};
template <class T>
T *PointType::createPoint(const Point &P, unsigned int index ) {
unsigned int counter = 0;
T *p = new T[pointdim];
p[counter++] = P.x;
p[counter++] = P.y;
p[counter++] = P.z;
if (types & USE_REFLECTANCE) {
p[counter++] = P.reflectance;
}
if (types & USE_NORMAL) {
p[counter++] = P.nx;
p[counter++] = P.ny;
p[counter++] = P.nz;
}
if (types & USE_TEMPERATURE) {
p[counter++] = P.temperature;
}
if (types & USE_AMPLITUDE) {
p[counter++] = P.amplitude;
}
if (types & USE_DEVIATION) {
p[counter++] = P.deviation;
}
if (types & USE_TYPE) {
p[counter++] = P.type;
}
if (types & USE_COLOR) {
memcpy(&p[counter], P.rgb, 3);
counter++;
}
if (types & USE_TIME) {
// p[counter++] = P.timestamp;
}
if (types & USE_INDEX) {
p[counter++] = index;
}
return p;
}
template <class T>
Point PointType::createPoint(T *p) {
Point P;
unsigned int counter = 0;
P.x = p[counter++];
P.y = p[counter++];
P.z = p[counter++];
if (types & USE_REFLECTANCE) {
P.reflectance = p[counter++];
}
if (types & USE_NORMAL) {
p[counter++] = P.nx;
p[counter++] = P.ny;
p[counter++] = P.nz;
}
if (types & USE_TEMPERATURE) {
P.temperature = p[counter++];
}
if (types & USE_AMPLITUDE) {
P.amplitude = p[counter++];
}
if (types & USE_DEVIATION) {
P.deviation = p[counter++];
}
if (types & USE_TYPE) {
P.type = p[counter++];
}
if (types & USE_COLOR) {
memcpy(P.rgb, &p[counter], 3);
counter++;
}
if (types & USE_TIME) {
// P.timestamp = p[counter++];
}
return P;
}
template <class T>
T *PointType::createPoint(unsigned int i, unsigned int index) {
unsigned int counter = 0;
T* p = new T[pointdim];
for(unsigned int j = 0; j < 3; ++j)
p[counter++] = (*m_xyz)[i][j];
// if a type is requested try to write the value if the scan provided one
if (types & USE_REFLECTANCE) {
p[counter++] = (m_reflectance? (*m_reflectance)[i]: 0);
}
if (types & USE_NORMAL) {
for(unsigned int j = 0; j < 3; ++j)
p[counter++] = (*m_normal)[i][j];
}
if (types & USE_TEMPERATURE) {
p[counter++] = (m_temperature? (*m_temperature)[i]: 0);
}
if (types & USE_AMPLITUDE) {
p[counter++] = (m_amplitude? (*m_amplitude)[i]: 0);
}
if (types & USE_DEVIATION) {
p[counter++] = (m_deviation? (*m_deviation)[i]: 0);
}
if (types & USE_TYPE) {
p[counter++] = (m_type? (*m_type)[i]: 0);
}
if (types & USE_COLOR) {
if(m_rgb)
memcpy(&p[counter], (*m_rgb)[i], 3);
else
p[counter] = 0;
counter++;
}
if (types & USE_TIME) {
}
if (types & USE_INDEX) {
p[counter++] = index;
}
return p;
}
template<typename T>
T** PointType::createPointArray(Scan* scan)
{
// access data with prefetching
useScan(scan);
// create a float array with requested attributes by pointtype via createPoint
unsigned int nrpts = getScanSize(scan);
T** pts = new T*[nrpts];
for(unsigned int i = 0; i < nrpts; i++) {
pts[i] = createPoint<T>(i);
}
// unlock access to data, remove unneccessary data fields
clearScan();
return pts;
}
#endif