Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Scan.hpp"
00011 #include <algorithm>
00012 #include <cmath>
00013 #include <limits>
00014 #include "ScannerInfo.hpp"
00015 #include "../tools/errorhandler.hpp"
00016 #include <set>
00017 #include "../tools/toolbox.hpp"
00018
00019 namespace datatypes
00020 {
00021
00022
00023
00024
00025
00026 Scan::Scan (size_type maxPoints)
00027 : m_flags(0)
00028 , m_scanNumber(0x0000)
00029 , m_points()
00030 {
00031 m_datatype = Datatype_Scan;
00032 m_points.reserve(maxPoints);
00033
00034 m_beVerbose = false;
00035 }
00036
00037 Scan::Scan (const Scan& other)
00038 : m_points()
00039 {
00040 copy(other);
00041 }
00042
00043
00044 const UINT32 Scan::getUsedMemory() const
00045 {
00046 return (sizeof(*this) +
00047 (getNumPoints() * sizeof(ScanPoint)) +
00048 (m_scannerInfos.size() * sizeof(ScannerInfo)));
00049 }
00050
00051
00052 Scan& Scan::copy (const Scan& other)
00053 {
00054
00055
00056
00057
00058
00059
00060
00061
00062 m_flags = other.m_flags;
00063 m_scanNumber = other.m_scanNumber;
00064
00065
00066 m_sourceId = other.m_sourceId;
00067 m_datatype = other.m_datatype;
00068
00069
00070 m_points = other.m_points;
00071 m_points.reserve (other.capacity());
00072
00073
00074 m_scannerInfos = other.m_scannerInfos;
00075
00076
00077 m_beVerbose = other.m_beVerbose;
00078
00079 return *this;
00080 }
00081
00082
00083
00084
00085
00086 UINT32 Scan::getTotalObjectSize()
00087 {
00088 UINT32 size;
00089
00090 size = sizeof(*this);
00091 size += getNumPoints() * sizeof(ScanPoint);
00092 size += m_scannerInfos.size() * sizeof(ScannerInfo);
00093
00094 return size;
00095 }
00096
00097 Scan& Scan::operator= (const Scan& other)
00098 {
00099 return copy(other);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 void Scan::clear ()
00134 {
00135
00136 m_flags = 0;
00137 m_scanNumber = 0x0000;
00138 m_sourceId = 0;
00139
00140 m_points.clear();
00141 m_scannerInfos.clear();
00142 }
00143
00144
00145 Scan::~Scan()
00146 {
00147 }
00148
00149 void Scan::resize(size_type new_size, const ScanPoint& default_point)
00150 {
00151 if (size_type((UINT16)new_size) != new_size)
00152 {
00153 throw std::out_of_range ("Scan::resize was called with new size larger than what fits into UINT16: " + toString(new_size) + " but only 65536 is allowed!");
00154 }
00155
00156 m_points.resize(new_size, default_point);
00157 }
00158
00159 void Scan::reserve(size_type new_capacity)
00160 {
00161 if (size_type((UINT16)new_capacity) != new_capacity)
00162 {
00163 throw std::out_of_range ("Scan::reserve was called with new capacity larger than what fits into UINT16: " + toString(new_capacity) + " but only 65536 is allowed!");
00164 }
00165
00166 m_points.reserve(new_capacity);
00167 }
00168
00173 ScanPoint& Scan::addNewPoint()
00174 {
00175 m_points.push_back(ScanPoint());
00176 return m_points.back();
00177 }
00178
00179 void Scan::setVehicleCoordinates(bool inVehicleCoordinates)
00180 {
00181 if (inVehicleCoordinates)
00182 m_flags |= FlagVehicleCoordinates;
00183 else
00184 m_flags &= ~FlagVehicleCoordinates;
00185 }
00186
00187
00188
00189
00190 static bool isDescendingAngle (const ScanPoint& P1, const ScanPoint& P2)
00191 {
00192 return (P1.getHAngle() > P2.getHAngle());
00193 }
00194
00195 void Scan::sort()
00196 {
00197 std::sort(getPointListBegin(), getPointListEnd(), isDescendingAngle);
00198 }
00199
00200 void Scan::addCartesianOffset(double offsetX, double offsetY, double offsetZ)
00201 {
00202 for (PointList::iterator point = getPointListBegin(); point != getPointListEnd(); point++)
00203 point->addCartesianOffset(offsetX, offsetY, offsetZ);
00204 }
00205
00206 void Scan::addPolarOffset(double distOffset, double hAngleOffset, double vAngleOffset)
00207 {
00208 for (PointList::iterator point = getPointListBegin(); point != getPointListEnd(); point++)
00209 point->addPolarOffset(distOffset, hAngleOffset, vAngleOffset);
00210 }
00211
00212 void Scan::setScannerInfos(const ScannerInfoVector& v)
00213 {
00214
00215
00216 std::set<UINT8> availableDevicesOnce;
00217 std::set<UINT8> availableDevicesTwice;
00218 for (ScannerInfoVector::const_iterator it = v.begin();
00219 it != v.end(); it++)
00220 {
00221 const ScannerInfo& sinfo = *it;
00222 const UINT8 deviceID = sinfo.getDeviceID();
00223
00224
00225 if (availableDevicesOnce.count(deviceID) == 0)
00226 {
00227
00228 availableDevicesOnce.insert(deviceID);
00229 }
00230 else
00231 {
00232
00233 throw std::logic_error("Scan::setScannerInfos called with a list (size=" +
00234 ::toString(v.size()) + ") that contains two ScannerInfos with device ID " +
00235 ::toString(int(deviceID)) + ", type " + ScannerInfo::scannerTypeToString(sinfo.getScannerType()) +
00236 ". This is not allowed - for each scanner at most one ScannerInfo may be stored in the ScannerInfoVector.");
00237 }
00238 }
00239
00240 m_scannerInfos = v;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 bool Scan::transformToVehicleCoordinatesUnsorted()
00300 {
00301
00302 if ((getFlags() & FlagVehicleCoordinates) != 0)
00303 {
00304
00305
00306 return true;
00307 }
00308
00309
00310 if (getScannerInfos().empty())
00311 {
00312 printWarning("Scan::convertToVehicleCoordinates: Scan (#" + ::toString(getScanNumber()) +
00313 ") has empty ScannerInfos - no conversion possible, aborting!");
00314 return false;
00315 }
00316
00317
00318 Position3D mountPos = m_scannerInfos.at(0).getMountingPosition();
00319
00320
00321
00322 for (Scan::iterator sptIt = begin(); sptIt != end(); sptIt++)
00323 {
00324 Point3D pt = sptIt->toPoint3D();
00325 mountPos.transformToVehicle(&pt);
00326 sptIt->setPoint3D(pt);
00327 }
00328
00329
00330
00331 setFlags(getFlags() | FlagVehicleCoordinates );
00332
00333
00334 for (ScannerInfoVector::iterator siIt = getScannerInfos().begin(); siIt != getScannerInfos().end(); siIt++)
00335 {
00336 ScannerInfo& sinfo = *siIt;
00337 sinfo.setScanFlags(sinfo.getScanFlags() | FlagVehicleCoordinates);
00338 }
00339
00340 return true;
00341 }
00342
00343 bool Scan::transformToVehicleCoordinates()
00344 {
00345 const bool r = transformToVehicleCoordinatesUnsorted();
00346
00347
00348
00349 sort();
00350
00351 return r;
00352 }
00353
00354
00355 Scan::ScannerInfoVector& Scan::getScannerInfos()
00356 {
00357 return m_scannerInfos;
00358 }
00359
00360 const ScannerInfo* Scan::getScannerInfoByDeviceId(UINT8 id) const
00361 {
00362 for (ScannerInfoVector::const_iterator it = m_scannerInfos.begin();
00363 it != m_scannerInfos.end();
00364 it++)
00365 {
00366 if ((*it).getDeviceID() == id)
00367 return &(*it);
00368 }
00369
00370 return NULL;
00371 }
00372
00373 void Scan::clearLabelFlag(Scan::ScanFlags scanFlag)
00374 {
00375 UINT32 test = ~(scanFlag);
00376 m_flags &= test;
00377 }
00378
00379 }