17 #include <QCoreApplication>
32 return "Internal error: bad input";
34 return "Error: not enough memory";
36 return "Error: process cancelled by user";
38 return "Error: depth buffer is void (check input cloud and angular "
45 return QString(
"unknown error (code: %i)").arg(errorCode);
53 m_pitchAnglesAreShifted(false),
57 m_yawAnglesAreShifted(false),
58 m_rotationOrder(rotOrder),
68 m_phiMin(sensor.m_phiMin),
69 m_phiMax(sensor.m_phiMax),
70 m_deltaPhi(sensor.m_deltaPhi),
71 m_pitchAnglesAreShifted(sensor.m_pitchAnglesAreShifted),
72 m_thetaMin(sensor.m_thetaMin),
73 m_thetaMax(sensor.m_thetaMax),
74 m_deltaTheta(sensor.m_deltaTheta),
75 m_yawAnglesAreShifted(sensor.m_yawAnglesAreShifted),
76 m_rotationOrder(sensor.m_rotationOrder),
77 m_sensorRange(sensor.m_sensorRange),
78 m_uncertainty(sensor.m_uncertainty) {}
121 double posIndex )
const {
139 destPoint.
x = atan2(P.
y, P.
x);
142 destPoint.
y = atan2(P.
z, sqrt(P.
x * P.
x + P.
y * P.
y));
148 destPoint.
x = -atan2(sqrt(P.
y * P.
y + P.
z * P.
z), P.
x);
151 destPoint.
y = -atan2(P.
y, P.
z);
182 i =
static_cast<unsigned>(
193 j =
static_cast<unsigned>(
204 double posIndex )
const {
205 if (!cloud || theNorms.capacity() == 0)
return nullptr;
208 if (
size == 0)
return nullptr;
212 static const CCVector3 zeroNormal(0, 0, 0);
213 normalGrid->resize(
size, zeroNormal);
214 }
catch (
const std::bad_alloc&) {
230 unsigned pointCount = cloud->
size();
231 for (
unsigned i = 0; i < pointCount; ++i) {
255 S.
z = -N.
dot(U) / distToSensor;
259 sqrt((
PC_ONE - S.
z * S.
z) / squareS2D);
260 S.
x = coef * (S2.
x - Q.
x);
261 S.
y = coef * (S2.
y - Q.
y);
288 normalGrid->at(i).normalize();
297 if (!cloud || theColors.capacity() == 0)
return nullptr;
305 std::vector<size_t> pointPerDMCell;
307 pointPerDMCell.resize(gridSize, 0);
308 }
catch (
const std::bad_alloc&) {
314 std::vector<ecvColor::Rgbf> colorAccumGrid;
318 colorAccumGrid.resize(gridSize, blackF);
319 }
catch (
const std::bad_alloc&) {
329 }
catch (
const std::bad_alloc&) {
336 unsigned pointCount = cloud->
size();
339 for (
unsigned i = 0; i < pointCount; ++i) {
356 ++pointPerDMCell[index];
367 for (
unsigned i = 0; i < gridSize; ++i) {
368 if (pointPerDMCell[i] != 0) {
398 bool allowLoop =
true) {
400 Interval firstEmptyPart, bestEmptyPart, currentEmptyPart;
402 for (
size_t i = 0; i < values.size(); ++i) {
404 if (values[i] == intValue) {
406 if (currentEmptyPart.
span == 0) {
407 currentEmptyPart.
start =
static_cast<int>(i);
409 currentEmptyPart.
span++;
412 if (currentEmptyPart.
span != 0) {
415 if (currentEmptyPart.
start == 0) {
416 firstEmptyPart = currentEmptyPart;
418 if (bestEmptyPart.
span < currentEmptyPart.
span) {
419 bestEmptyPart = currentEmptyPart;
427 if (allowLoop && firstEmptyPart.
span != 0 &&
428 currentEmptyPart.
span != 0) {
429 currentEmptyPart.
span += firstEmptyPart.
span;
433 if (bestEmptyPart.
span < currentEmptyPart.
span) {
434 bestEmptyPart = currentEmptyPart;
437 return bestEmptyPart;
448 std::vector<bool> nonEmptyAnglesYaw, nonEmptyAnglesPitch;
450 nonEmptyAnglesYaw.resize(360,
false);
451 nonEmptyAnglesPitch.resize(360,
false);
452 }
catch (
const std::bad_alloc&) {
460 unsigned pointCount = theCloud->
size();
467 for (
unsigned i = 0; i < pointCount; ++i) {
476 assert(angleYaw >= -180 && angleYaw <= 180);
479 nonEmptyAnglesYaw[180 + angleYaw] =
true;
483 else if (maxYaw < Q.
x)
486 minYaw = maxYaw = Q.
x;
492 assert(anglePitch >= -180 && anglePitch <= 180);
493 if (anglePitch == 180) anglePitch = -180;
494 nonEmptyAnglesPitch[180 + anglePitch] =
true;
498 else if (maxPitch < Q.
y)
501 minPitch = maxPitch = Q.
y;
504 if (depth > maxDepth) maxDepth = depth;
509 Interval::FindBiggest<bool>(nonEmptyAnglesYaw,
false,
true);
511 Interval::FindBiggest<bool>(nonEmptyAnglesPitch,
false,
true);
514 (bestEmptyPartYaw.
start != 0 && bestEmptyPartYaw.
span > 1 &&
515 bestEmptyPartYaw.
start + bestEmptyPartYaw.
span < 360);
517 (bestEmptyPartPitch.
start != 0 && bestEmptyPartPitch.
span > 1 &&
518 bestEmptyPartPitch.
start + bestEmptyPartPitch.
span < 360);
523 for (
unsigned i = 0; i < pointCount; ++i) {
532 else if (maxYaw < Q.
x)
537 else if (maxPitch < Q.
y)
540 minYaw = maxYaw = Q.
x;
541 minPitch = maxPitch = Q.
y;
572 int width =
static_cast<int>(
597 }
catch (
const std::bad_alloc&) {
609 unsigned pointCount = theCloud->
size();
613 if (projectedCloud) {
614 projectedCloud->
clear();
615 if (!projectedCloud->
reserve(pointCount) ||
630 pdlg.
setInfo(QObject::tr(
"Points: %L1").arg(pointCount));
632 QCoreApplication::processEvents();
634 for (
unsigned i = 0; i < pointCount; ++i) {
644 zBuf = std::max(zBuf, depth);
648 if (projectedCloud) {
722 const double halfHeadSize = 0.3;
723 double scale =
static_cast<double>(
m_scale);
727 double axisLength = halfHeadSize * scale;
750 Eigen::Vector3d minCorner(-halfHeadSize, -halfHeadSize, -halfHeadSize);
751 Eigen::Vector3d maxCorner(halfHeadSize, halfHeadSize, halfHeadSize);
754 ccBBox bbox(minCorner, maxCorner);
766 m_leg.
points_.push_back(Eigen::Vector3d(-scale, -scale, -scale));
767 m_leg.
points_.push_back(Eigen::Vector3d(-scale, scale, -scale));
768 m_leg.
points_.push_back(Eigen::Vector3d(scale, 0.0, -scale));
794 if (!withGLFeatures) {
843 CVLog::Warning(
"[ccGBLSensor::applyViewport] No associated display!");
911 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
912 if (dataVersion < 38) {
921 if (out.write((
const char*)&rotOrder, 4) < 0)
return WriteError();
924 QDataStream outStream(&out);
944 return std::max(
static_cast<short>(38),
956 uint32_t rotOrder = 0;
957 if (in.read((
char*)&rotOrder, 4) < 0)
return ReadError();
961 QDataStream inStream(&in);
972 if (dataVersion < 38) {
973 ScalarType sensorRange{};
974 ScalarType uncertainty{};
990 if (dataVersion >= 38) {
constexpr unsigned char POINT_VISIBLE
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
constexpr unsigned char POINT_HIDDEN
constexpr unsigned char POINT_OUT_OF_FOV
constexpr unsigned char POINT_OUT_OF_RANGE
Vector3Tpl< double > CCVector3d
Double 3D Vector.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Type dot(const Vector3Tpl &v) const
Dot product.
Type norm() const
Returns vector norm.
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
unsigned height
Buffer height.
PointCoordinateType deltaTheta
Yaw step (may differ from the sensor's)
std::vector< PointCoordinateType > zBuff
Z-Buffer grid.
void clear()
Clears the buffer.
PointCoordinateType deltaPhi
Pitch step (may differ from the sensor's)
unsigned width
Buffer width.
virtual void lockVisibility(bool state)
Locks/unlocks visibility.
Ground-based Laser sensor.
void projectPoint(const CCVector3 &sourcePoint, CCVector2 &destPoint, PointCoordinateType &depth, double posIndex=0) const
Projects a point in the sensor world.
bool computeDepthBuffer(cloudViewer::GenericCloud *cloud, int &errorCode, ccPointCloud *projectedCloud=nullptr)
PointCoordinateType m_thetaMin
Minimal yaw limit (in radians)
PointCoordinateType m_deltaTheta
Yaw step (in radians)
PointCoordinateType m_thetaMax
Maximal yaw limit (in radians)
ccBBox getOwnFitBB(ccGLMatrix &trans) override
Returns best-fit bounding-box (if available)
bool m_yawAnglesAreShifted
ROTATION_ORDER m_rotationOrder
Mirrors rotation order.
PointCoordinateType getMinPitch() const
Returns the minimal pitch limit (in radians)
ROTATION_ORDER
The order of inner-rotations of the sensor (body/mirrors)
PointCoordinateType m_phiMin
Minimal pitch limit (in radians)
PointCoordinateType m_deltaPhi
Pitch step (in radians)
bool m_pitchAnglesAreShifted
PointCoordinateType getMinYaw() const
Returns the minimal yaw limit (in radians)
void setYawRange(PointCoordinateType minTheta, PointCoordinateType maxTheta)
Sets the yaw scanning limits.
std::vector< CCVector3 > NormalGrid
2D grid of normals
ColorGrid * projectColors(cloudViewer::GenericCloud *cloud, const ColorGrid &rgbColors) const
bool convertToDepthMapCoords(PointCoordinateType yaw, PointCoordinateType pitch, unsigned &i, unsigned &j) const
ccGBLSensor(ROTATION_ORDER rotOrder=YAW_THEN_PITCH)
Default constructor.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
void setPitchRange(PointCoordinateType minPhi, PointCoordinateType maxPhi)
Sets the pitch scanning limits.
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
NormalGrid * projectNormals(cloudViewer::GenericCloud *cloud, const NormalGrid &norms, double posIndex=0) const
Projects a set of point cloud normals in the sensor world.
cloudViewer::geometry::LineSet m_leg
bool computeAutoParameters(cloudViewer::GenericCloud *theCloud)
Computes angular parameters automatically (all but the angular steps!)
static QString GetErrorString(int errorCode)
Returns the error string corresponding to an error code.
PointCoordinateType m_phiMax
Maximal pitch limit (in radians)
std::vector< ecvColor::Rgb > ColorGrid
2D grid of colors
void drawMeOnly(CC_DRAW_CONTEXT &context) override
Draws the entity only (not its children)
bool applyViewport() override
Apply sensor 'viewport' to a 3D view.
short minimumFileVersion_MeOnly() const override
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
unsigned char checkVisibility(const CCVector3 &P) const override
void setSensorRange(PointCoordinateType range)
Sets the sensor max. range.
PointCoordinateType getMaxYaw() const
Returns the maximal yaw limit (in radians)
ccDepthBuffer m_depthBuffer
Associated Z-buffer.
void setYawStep(PointCoordinateType dTheta)
Sets the yaw step.
ecvOrientedBBox m_obbHead
PointCoordinateType m_uncertainty
Z-buffer uncertainty.
virtual void hideShowDrawings(CC_DRAW_CONTEXT &context) override
PointCoordinateType m_sensorRange
Sensor max range.
ROTATION_ORDER getRotationOrder() const
Returns the sensor internal rotations order.
void clearDepthBuffer()
Removes the associated depth buffer.
cloudViewer::geometry::LineSet m_axis
PointCoordinateType getMaxPitch() const
Returns the maximal pitch limit (in radians)
void setPitchStep(PointCoordinateType dPhi)
Sets the pitch step.
virtual void clearDrawings() override
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
T * getTranslation()
Retruns a pointer to internal translation.
T * data()
Returns a pointer to internal data.
static ccGLMatrixTpl< double > FromViewDirAndUpDir(const Vector3Tpl< double > &forward, const Vector3Tpl< double > &up)
Generates a 'viewing' matrix from a looking vector and a 'up' direction.
void invert()
Inverts transformation.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
void initFromParameters(T alpha_rad, const Vector3Tpl< T > &axis3D, const Vector3Tpl< T > &t3D)
Inits transformation from a rotation axis, an angle and a translation.
static Eigen::Matrix< double, 4, 4 > ToEigenMatrix4(const ccGLMatrixTpl< float > &mat)
Float version of ccGLMatrixTpl.
Double version of ccGLMatrixTpl.
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
QString getViewId() const
virtual void setSelectionBehavior(SelectionBehavior mode)
Sets selection behavior (when displayed)
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
void clear() override
Clears the entity from all its points and features.
virtual void applyRigidTransformation(const ccGLMatrix &trans) override
Applies a rigid transformation (rotation + translation)
Generic sensor interface.
short minimumFileVersion_MeOnly() const override
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
PointCoordinateType m_scale
Sensor graphic representation scale.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
ccIndexedTransformationBuffer * m_posBuffer
Positions buffer (optional)
ccGLMatrix m_rigidTransformation
Rigid transformation between this sensor and its associated positions.
double m_activeIndex
Active index (for displayed position, etc.)
bool getAbsoluteTransformation(ccIndexedTransformation &trans, double index) const
bool getActiveAbsoluteTransformation(ccIndexedTransformation &trans) const
Gets currently active absolute transformation.
ecvColor::Rgb m_color
Color of the sensor.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
static void ScalarsFromDataStream(QDataStream &stream, int flags, ScalarType *out, unsigned count=1)
static void CoordsFromDataStream(QDataStream &stream, int flags, PointCoordinateType *out, unsigned count=1)
virtual void placeIteratorAtBeginning()=0
Sets the cloud iterator at the beginning.
virtual const CCVector3 * getNextPoint()=0
Returns the next point (relatively to the global iterator position)
virtual unsigned size() const =0
Returns the number of points.
bool oneStep()
Increments total progress value of a single unit.
void SetColor(const Eigen::Vector3d &color)
Sets the bounding box color.
void setPointScalarValue(unsigned pointIndex, ScalarType value) override
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
bool enableScalarField() override
std::vector< Eigen::Vector3d > points_
Points coordinates.
std::vector< Eigen::Vector3d > colors_
RGB colors of lines.
std::vector< Eigen::Vector2i > lines_
Lines denoted by the index of points forming the line.
virtual LineSet & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
static Eigen::Vector3d ToEigen(const Type col[3])
static ecvOrientedBBox CreateFromAxisAlignedBoundingBox(const ccBBox &aabox)
virtual ecvOrientedBBox & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
Graphical progress indicator (thread-safe)
virtual void setInfo(const char *infoStr) override
Notifies some information about the ongoing process.
virtual void start() override
virtual void setMethodTitle(const char *methodTitle) override
Notifies the algorithm title.
unsigned char ColorCompType
Default color components type (R,G and B)
#define MACRO_Draw3D(context)
static const int s_MaxDepthBufferSize
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
float RadiansToDegrees(int radians)
Convert radians to degrees.
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
constexpr Rgb black(0, 0, 0)
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb green(0, MAX, 0)
constexpr Rgb yellow(MAX, MAX, 0)
Eigen::Matrix< Index, 2, 1 > Vector2i
int start
Interval start index.
static Interval FindBiggest(const std::vector< T > &values, T intValue, bool allowLoop=true)
Finds the biggest contiguous interval.
Interval()
Default constructor.
unsigned char currentLineWidth